MySql or和in的区别

MySql or和in的区别,第1张

网上有很多人都在谈论or与in的使用,有的说二者没有什么区别,其实不然,估计是测试做的不够,其实or的效率为O(n),而in的效率为O(log2n),当基数越大时,in的效率就能凸显出来了。

有人做了这么一组实验(测试库数据为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个链接,虽然不会那么夸张,但是如果是高并发的情况。。就不容乐观了。

所以推荐使用第二个。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/zaji/6152020.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-03-16
下一篇2023-03-16

发表评论

登录后才能评论

评论列表(0条)

    保存