NOT EXISTS和NOT IN之间有什么区别,左连接是NULL?

在我看来,你可以在SQL查询中使用NOT EXISTS,NOT IN或LEFT JOIN WHERE IS来做同样的事情。 例如:

SELECT a FROM table1 WHERE a NOT IN (SELECT a FROM table2) SELECT a FROM table1 WHERE NOT EXISTS (SELECT * FROM table2 WHERE table1.a = table2.a) SELECT a FROM table1 LEFT JOIN table2 ON table1.a = table2.a WHERE table1.a IS NULL 

我不确定是否所有的语法正确,但这些是我见过的一般技术。 为什么我会select使用一个呢? 性能不同…? 哪一个是最快/最有效的? (如果取决于实施,我什么时候可以使用每一个?)

  • 不在与不存在与左join/是空的:SQL Server

  • 不在与不存在与左join/是NULL:PostgreSQL

  • 不在与不存在与左join/是空的:甲骨文

  • 不在与不存在与左join/是空的:MySQL

简而言之:

NOT IN有点不同:如果列表中只有一个NULL ,它就不匹配。

  • MySQLNOT EXISTS效率NOT EXISTS一些

  • SQL ServerLEFT JOIN / IS NULL效率较低

  • PostgreSQLNOT IN效率较低

  • Oracle ,这三种方法都是一样的。

如果数据库擅长优化查询,则前两个将转化为接近第三个的数据。

对于像你这样简单的情况来说,应该没有什么区别,因为它们全部都会作为连接来执行。 在更复杂的查询中,数据库可能无法not innot exists查询中进行联接。 在这种情况下,查询会变慢很多。 另一方面,如果没有可以使用的索引,联接也可能performance不佳,因为使用联接并不意味着你是安全的。 您将必须检查查询的执行计划,以确定是否有任何性能问题。

假设你正在避免空值,它们都是使用标准SQL编写反连接的方法。

使用EXCEPT是一个明显的EXCEPT

 SELECT a FROM table1 EXCEPT SELECT a FROM table2 

在Oracle中请注意,您需要使用MINUS运算符(可以说是一个更好的名字):

 SELECT a FROM table1 MINUS SELECT a FROM table2 

说到专有语法,可能还有非标准的等价物值得研究,这取决于你正在使用的产品,例如在SQL Server中的OUTER APPLY (类似):

 SELECT t1.a FROM table1 t1 OUTER APPLY ( SELECT t2.a FROM table2 t2 WHERE t2.a = t1.a ) AS dt1 WHERE dt1.a IS NULL; 

当需要在多字段主键的表中插入数据时,考虑到它会快得多(我在Access中试过,但是我认为在任何数据库中)不要检查“在表中不存在'这样的值'的logging, – 而不是插入到表中,并且多余的logging(通过键)不会被插入两次。

性能视angular总是避免使用反向关键字,如NOT IN,NOT EXISTS,…因为要检查反向项目,DBMS需要遍历所有可用项目并删除反向select。