ORACLE中exists(not exists)与in(not in)的对比及null值处理

(1) in和exists
in和exists的用法分别如下:
SELECT  *  FROM  table_name1 A WHERE A.id  IN  (SELECT B.id FROM table_name2 B);
SELECT * FROM table_name1 A WHERE EXISTS (SELECT 1 FROM table_name2 B WHERE B.id=A.id) ;
in和exists都可以用多表联合差查询。in是先进子查询,然后内外表进性笛卡尔乘积,再筛选符合条件的数据;exists是对外表进性循环,查看外表是否有和子查询匹配的数据。

如果外(主)查询的记录远大于子查询记录数,且外查询使用了索引字段,则使用IN效率高;
如果外(主)查询的记录数远小于内查询的记录数,且子查询使用了内表的索引,则使用EXISTS效率高。

还有一种联合查询如下,这种查询对内外表使用笛卡尔乘积,效率最差。
SELECT A .* FROM table_name1 A , table_name2 B  WHERE B.id=A.id ;


(2)not in和not exists
NOT IN对内外表都要进行扫描,而NOT EXISTS子查询仍旧能够使用内表的索引,因此NOT EXISTS通常都比NOT IN效率高。

(3)对于null的处理
对于null的处理。由于null是未知,不能够用=或者<>进行比较(比较的结果未知),只能用is null或者is not null来判断是否是null。
in和exists对于null的处理结果是相同的,对于IN,如果子查询中有NULL值,即便外查询的条件列有NULL值,返回的结果也不会有null,因为null=null返回不是true;对于EXISTS,如果查询的条件列有NULL值,由于null=null返回不是true,因此exists对于该行数据返回false,条件为null值的行也在最终的结果集合中。


NOT EXISTS 和NOT IN对于NULL的结果则大不相同,使用not in的话,如果子查询中有null,则返回的结果全空,例如 where 1 not in (2, null) 等价于where 1!=2 &&1!=null,由于后者为false,因此最终返回的结果为空;

对于not exists,循环查照外表中符合内查询条件的数据,外表的条件列的某个数据与内表的条件列的所有数据比较(子查询中是或关系),比较结果作为子查询的结果。如果内表中条件列数据全是null,则返回外表所有数据;如果内表不全部是null,那么当外表的条件列值为null时候,或者外表条件列的值没有匹配配到内表条件列的任何值时候,返回外表此行数据。

猜你喜欢

转载自blog.csdn.net/poetteaes/article/details/80375812