
有人做了这么一组实验(测试库数据为1000万条记录):A组分别用or与in查询3条记录,B组分别用or与in查询120条记录,C组分别用or与in查询500条记录,D组分别用or与in查询1000条记录.
第一种情况,目标列为主键的情况,4组测试执行计划一样,执行的时间也基本没有区别。
A组or和in的执行时间: or的执行时间为:0.002s in的执行时间为:0.002s
B组or和in的执行时间: or的执行时间为:0.004s in的执行时间为:0.004s
C组or和in的执行时间: or的执行时间为:0.006s in的执行时间为:0.005s
D组or和in的执行时间: or的执行时间为:0.017s in的执行时间为:0.014s
第二种情况,目标列为一般索引的情况,4组测试执行计划一样,执行的时间也基本没有区别。
A组or和in的执行时间: or的执行时间为:0.002s in的执行时间为:0.002s
B组or和in的执行时间: or的执行时间为:0.006s in的执行时间为:0.005s
C组or和in的执行时间: or的执行时间为:0.008s in的执行时间为:0.008s
D组or和in的执行时间: or的执行时间为:0.020s in的执行时间为:0.019s
第三种情况,目标列没有索引的情况,4组测试执行计划就不一样,执行的时间也有了很大的区别。
A组or和in的执行时间: or的执行时间为:5.016s in的执行时间为:5.071s
B组or和in的执行时间: or的执行时间为:1min 02s in的执行时间为:5.018s
C组or和in的执行时间: or的执行时间为:1min 50s in的执行时间为:5.010s
D组or和in的执行时间: or的执行时间为:6min 13s in的执行时间为:5.047s
结论:
in和or的效率,取决目标条件列是否有索引或者是否是主键,如果有索引或者主键性能没啥差别,如果没有索引,in的性能要远远优于or.
如说两张表一张是用户表TDefUser(userid,address,phone),一张是消费表TAccConsume(userid,time,amount),我要查消费超过5000的用户记录,那么可以写select * from TDefUser where exists (select 1 from TAccConsume where TDefUser.userid=TAccConsume.userid and TAccConsume.amount>5000)
也可以:
select * from TDefUser where userid in (select userid from TAccConsume where TAccConsume.amount>5000)
exists()后面的子查询被称做相关子查询其运行方式是先运行主查询一次 再去子查询里查询与其对应的结果 如果是ture则输出,反之则不输出.再根据主查询中的每一行去子查询里去查询. in()后面的子查询 是返回结果集的,换句话说执行次序和exists()不一样.子查询先产生结果集,然后主查询再去结果集里去找符合要求的字段列表去.符合要求的输出,反之则不输出.
性能影响的话,这个是没有固定那一个好,要针对自身条件来使用。
一直以来认为exists比in效率高的说法是不准确的。如果查询的两个表大小相当,那么用in和exists差别不大。 如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in: 例如:表A(小表),表B(大表)
1:
select * from A where cc in (select cc from B) 效率低,用到了A表上cc列的索引;
select * from A where exists(select cc from B where cc=A.cc) 效率高,用到了B表上cc列的索引。
相反的
2:
select * from B where cc in (select cc from A) 效率高,用到了B表上cc列的索引;
select * from B where exists(select cc from A where cc=B.cc) 效率低,用到了A表上cc列的索引。
not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。in 与 =的区别
select name from student where name in ('zhang','wang','li','zhao')
与
select name from student where name='zhang' or name='li' or name='wang' or name='zhao'
的结果是相同的。
在查询效率上,是第一个快但是在对服务器的io压力上,倾向于使用第二个
因为一次查询就是一次mysql链接,占一个磁盘io。而且mysql一般的链接数是2000.你这一循环就一下占100个链接,虽然不会那么夸张,但是如果是高并发的情况。。就不容乐观了。
所以推荐使用第二个。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)