not in: 数据库通常会执行子查询,将结果集物化(除非优化器能够优化),然后进行主查询和子查询结果的比较。一般先执行子查询。
not exists: 通常使用关联子查询,这意味着子查询对于主查询的每一行都会执行一次(或者数据库优化器可能会将其转换为连接操作)。
在项目中遇到这样子的写法
select * from test01 t1 where t1.id=1
and t1.id not in (select t2.id from test02 t2 where t1.id=1 and t2.bcode='11')
and t1.bcode='14'
计划:
这里是先求select t2.id from test02 t2 where t2.bcode='11'的完整结果集后做成表达式作为test01的条件。也印证了我们前面解释。主查询id是主键条件,因此已经可以知道主查询结果集最多为1行,此时改成not exists,意味着与子查询执行一次,可想而知效率大大提升。
select * from test01 t1 where t1.id=1
and not exists (select 1 from test02 t2 where t1.id=1 and t1.id=t2.id and t2.bcode='11')
and t1.bcode='14'
计划:
符合我们的预期,性能大大提升。
对于主查询数据量较小的,not exists的效率往往会比not in高。
文章
阅读量
获赞
