MYSQL not in not exists 我们不一样, 坑你还得入?

MYSQL 8 这个版本已经和简单的查询慢慢的说再见了,MYSQL 8.017的功能Antijoin 也登录了,但问题大面积的MYSQL 5.X 怎么办,NOT IN 和 NOT EXISTS 大部分情况下,大部分人认为他们是相等的,但实际上是吗?在解决一个问题之前应该要理解他到底是一个什么情况,否则搞不清情况,往往会惹来一些麻烦。

下面是表结构

在salaries 表中插入一条在employees 表中没有的雇员的工资数据

select * from salaries as em where em.emp_no

not in (select emp_no from employees as sa );

select * from salaries as em where 

not exists (select * from employees as sa where sa.emp_no = em.emp_no)

两种方式都可以查询到数据,

SET @@profiling = 0;SET @@profiling_history_size = 0;SET @@profiling_history_size = 100;
SET @@profiling = 1;
下图可以很清晰的看到两个查询的耗时,not exists 是实实在在的 nest loop 了
,而not in 选择了一个特殊的索引,并没有“傻”到每行都要nest loop.

not in 很“聪明” 走了一个时间的索引,因为发现通过对比时间的方式可以找到“捷径”。 

所以NOT IN 并不与预想的,会比较慢。NOT EXISTS  也没有预想的那样。

那我们在换一种方式,看看 NOT  IN  和 NOT EXISTS  还有什么会让你觉得和你想的不一样。NOT IN  会让查询的准确性大打折扣吗?

我们生成两个表 proc  proc1,表结构没有任何的不一样,这是数据会有一些不同。

只是数据有不同

上面的图已经看出,NOT IN  给出的结果是不对的,也就是说如果表中的对比字段有NULL的情况,你将获得的结果与 not exists 是不一样的。查询在其结果中返回NULL,那么NOT in条件将失败。

所以还得在说一遍,表中的字段有没有NULL ,可绝对没有你想象的那么简单,很多时候想当然的结果可不是实际的结果。

最后还是要强调两点

1 初期的设计不好,后期的查询遇到的问题就会很多

2 认为和实际有些时候是不一样的

有问题共同分享,共同提高

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值