现在有两张表;r和p,在r_id上有索引
SELECT * FROM p, r WHERE r.r_id= p.c_id OR r.r_id=p.p_id;
现在这个sql通过explain查看发现r表是ALL全表扫描,请问为什么不使用索引,该如何优化,谢谢诸位
现在有两张表;r和p,在r_id上有索引
SELECT * FROM p, r WHERE r.r_id= p.c_id OR r.r_id=p.p_id;
现在这个sql通过explain查看发现r表是ALL全表扫描,请问为什么不使用索引,该如何优化,谢谢诸位
我创建了p表和r表,并按照你描述的,在r表上添加了r_id字段的索引,做了测试后来回答你的问题:
虽然添加了索引,但是
explain SELECT FROM p, r WHERE r.r_id= p.c_id union SELECT FROM p, r WHERE r.r_id=p.p_id;
这种联查导致索引失效。
可以试着下面这种写法:
explain select * from p where c_id in (select r_id from r)
union all
select * from p where p_id in (select r_id from r)
通过图中的结果可以看到,索引已经起作用了:
SELECT * FROM r , p WHERE r.r_id = p.c_id
UNION
SELECT * FROM r , p WHERE r.r_id = p.p_id
对于单个查询,IN是可以命中r.r_id索引,这是由mysql查询引擎自己决定。
1.多表联合查询,需要加筛选条件才能走索引,否则第二张表会扫全表。
2.一般union all多用来替代or,比union效率高,union适用于需要去重的场合,但是如果存在全表扫,union可能效率更低。
3.有时候可能因为数据量的大小,块分布,逻辑读次数等,实际结果可能反差很大,到底用哪种更快,不是绝对的,多用explain来看一下,数据量过大的情况,可以考虑分库分表,或者缓存的方式来处理,或者将部分逻辑计算放到代码层面处理。
15 回答8.4k 阅读
8 回答6.2k 阅读
5 回答3.2k 阅读✓ 已解决
3 回答3.6k 阅读✓ 已解决
1 回答4k 阅读✓ 已解决
3 回答1.8k 阅读✓ 已解决
3 回答6k 阅读
拆成SELECT FROM p, r WHERE r.r_id= p.c_id union SELECT FROM p, r WHERE r.r_id=p.p_id;