这种两个where_in的SQL可以优化吗?

2013-06-14 22:50:03 +08:00
 banxi1988
有一个表person,至少有name,memo字段。
=== ===
name memo
=== ===
名字1 说明1
名字2 说明2
名字3 说明2
名字4 说明2
==== =====

names = ['名字1','名字2']
memos = ['说明3','说明3']

显然names和memos是在程序中构造的。

SELECT *
FROM person
WHERE name in names AND memo in memos;

但是听说据说where_in的效率不高,更何况这种两个in的。
(为什么in子句的效率不高?)
3609 次点击
所在节点    MySQL
4 条回复
ipconfiger
2013-06-14 23:11:12 +08:00
MySql下in查詢會導致索引丟失,然後就變成了全表掃描,如果表大,那麼就鐵定了很慢。
in 子查詢的情況貌似可以match索引,但是你這裏兩個,鐵定了丟了。

如果in的內容不是很多的話,可以用union 來代替in。
優化sql最大的技巧就是 點一點右邊的感謝按鈕 ^_^
VYSE
2013-06-15 02:39:58 +08:00
你可以EXPLAIN看下有没有使用INDEX,现在的QUERY OPTIMIZER已经很智能去处理是否使用INDEX(有时一遍扫表效率更高)。
见官方文档:
Each table index is queried, and the best index is used unless the optimizer believes that it is more efficient to use a table scan. At one time, a scan was used based on whether the best index spanned more than 30% of the table, but a fixed percentage no longer determines the choice between using an index or a scan. The optimizer now is more complex and bases its estimate on additional factors such as table size, number of rows, and I/O block size.

如果一定要使用INDEX,在TABLE后面加上FORCE INDEX (names_index,memos_index)。
你这种情况相信MYSQL比盲目优化来的好,EXPLAIN还能参考语句效率。
另可试试拆成俩进行JOIN取代AND看看时间
banxi1988
2013-06-15 11:07:42 +08:00
@ipconfiger mysql下的子查询的in其实会优化成exists子句,不会丢失索引。
in的内容不多,平均10来条。union使用请明示。谢谢。
2269195609
2013-06-15 13:04:07 +08:00
若用等值连接查询呢,将后面两个列表组合成表,

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/72414

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX