今天改一个bug的时候,出现一个我差点认为我脑子理不清逻辑的问题,sql如下:
select * from so_aaa where status != '无效' and saleser = 123 -- and customer not in (select customer from so_bbb) and quantity > 0.1
查询结果为:
除去隐藏掉的条件外,是可以查询到数据的。 换句话说,如果数据查不出来,则隐藏能过得条件不满足!于是,我试着查询 not in 的数据。
select * from so_aaa where status != '无效' and saleser = 123 and customer not in (select customer from so_bbb) and quantity > 0.1
查询结果为:
查不到数据,那就是不满足这个条件,既然not in 不满足,那我换in呗。无论结果对不对,总有一个是对的吧!于是,让我怀疑自己脑子是不是迷糊了的现象发生了:
select * from so_aaa where status != '无效' and saleser = 123 and customer in (select customer from so_bbb) and quantity > 0.1
查询结果为:
依旧是空的?!!!然后我开始盘逻辑,插数据,发现,确实应该用not in;但是not in 为啥查询不到数据呢?
经过查阅网上的资料才知道,原来sql中,not in 要慎用!!!真的要判断,一个值是否存在与某个数组、集合或结果集中时,尽量使用 not exists 来代替 not in 。原因如下:
1、in:把内表和外表做hash连接,最好确定且有限的集合时使用;
not in:默认调用子查询,如果子查询中返回的任意一条记录有空值,查询将不会返回任何记录(这也是我用 not in 查询失败的原因,确实字表查询中,存在一条null的数据)
not exists:调用关联子查询
2、另一方面,not in 逻辑上不等于 not exists ,使用 not in 时,内外表都进行全表扫描,没有用到索引, not exists 的子表查询依然能用到表上的索引,所以使用 not exists 比使用 not in 来的快。
(ps:最后解决问题还是很开心,记录一下踩的小坑吧!每天进步一点点!)
文献参考如下,想看原文的点下方链接哦,感谢大佬们的援助: