mysql的复杂查询如何建索引?

2013-01-28 18:50:36 +08:00
 xing393939
SELECT * FROM feeds WHERE user_id=249229547 AND status < 10000 AND ((act_pid = 0 AND cat = 3) OR act_pid > 0) and is_friends = 0



这个查询怎么建索引,测试(user_id,status,act_pid,cat,is_friends)无效
3327 次点击
所在节点    MySQL
9 条回复
eric_zyh
2013-01-28 20:28:53 +08:00
(user_id,status,is_friends)
或 (user_id,status,is_friends,act_pid,cat)
plprapper
2013-01-28 20:41:34 +08:00
中间的OR逻辑 括号部分 从sql中拆出去吧,别放在sql里做。建索引除了sql外还和你的数据分布情况有关系。
xing393939
2013-01-29 09:41:27 +08:00
@eric_zyh 无效

@plprapper 如何拆分呢
techzhou
2013-01-29 09:43:42 +08:00
这个你不把explain贴出来么
keakon
2013-01-29 11:09:31 +08:00
把equal关系放前面啊,我估计执行时先查了is_friends,而不是status
Cadina
2013-01-29 11:11:36 +08:00
索引只看equal最大前缀,只有索引最后一个field用大于或小于才能完整利用索引
xing393939
2013-01-29 16:21:30 +08:00
@Cadina 那如何优化这个查询?
ipconfiger
2013-01-29 16:34:02 +08:00
都不用看Explain的结果

or 直接就导致索引失效了

(SELECT * FROM feeds WHERE user_id=249229547 AND status < 10000 AND act_pid = 0 AND cat = 3 and is_friends = 0) union all (SELECT * FROM feeds WHERE user_id=249229547 AND status < 10000 AND act_pid > 0 and is_friends = 0)

这样子拆成2个子查询再union all 加起来就不会丢索引了
ipconfiger
2013-01-29 16:36:43 +08:00
另外,mysql在一个查询里头只能match一个索引,所以你需要根据使用的顺序 将 user_id,status,act_pid和is_friends合起来建一个联合索引才能在4个条件里都match上索引

自己explain试试就知道了

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

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

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

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

© 2021 V2EX