4
回答
ORACLE IN 与NOT IN 的性能区别
百度AI开发者大赛带你边学边开发,赢100万奖金,加群:418589053   
业务问题大概可以这样描述,一个父表,一个子表,查询的结果是找到子表中没有使用父表id的记录,这种情况估计很多系统都会牵涉得到。让我们来举一个例子:

表一: 父表 parent

ORACLE <wbr>IN <wbr>与NOT <wbr>IN <wbr>的性能区别

表二: 子表 childen

ORACLE <wbr>IN <wbr>与NOT <wbr>IN <wbr>的性能区别

父表存储父亲,子表存储孩子,然后通过pid和父表关联,查询需要的结果是找到尚未有孩子的父亲。

我们来看一下查询语句的写法:

select * from parent where id not in (select pid from childen)

这种标准的写法在子表存在50万条的记录的时候,查询时间超过了10秒,远远大于原来的sql server服务器的一秒。我在解决的时候想到了一个方法:

select * from parent where id in

( select id from parent minus select pid from childen )

正常理解下,这个语句应该更加费时,但是事实完全出乎意料,这条语句不仅仅在子表存在大量记录的情况下速度良好,在子表少量数据的情况下速度也非常的好,基本在1秒内完成。

举报
华宰
发帖于7年前 4回/3K+阅
共有4个评论 最后回答: 6年前

一点愚见:

not in 需要判断记录是否在集合里面,一种最拙劣的做法,就是将这条记录与集合里的每一条都比较一次,当全部都比较之后发现不相等,才说是 not in

而 in 只需要在集合里面找出这条记录就可以了,至少不需要全部记录都比较过之后才能发现记录是否 in,而且,这个由于是主键,是否在内部会使用索引来加快速度?

永远不要用not in ,not in 只是为了兼容SQL标准而已。对于支持集合运算的数据库来说,

minus/except是正确的做法。

Not in 是Mysql 的做法,非关系型数据库的做法。

--- 共有 4 条评论 ---
宏哥@郭煜 : 两者逻辑不要,minus内部非常复杂.集合差操作时数据库的基本功能 6年前 回复
乌龟壳好像明白了,里面是子查询,数据库不好推测出可以使用索引。 6年前 回复
乌龟壳宏哥求指点:not in按照逻辑,也可以使用索引找,如果找不到就放弃呀,为何数据库要设计得会引起全表扫描呢? 6年前 回复
IdleMan不是还有exists么 6年前 回复
顶部