NOT EXISTS与NOT IN和LEFT JOIN之间的区别是什么?

fro*_*die 141 sql

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

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
Run Code Online (Sandbox Code Playgroud)

我不确定我的语法是否正确,但这些是我见过的一般技术.为什么我会选择使用一个而不是另一个?性能有所不同......?哪一个是最快/最有效的?(如果它取决于实施,我何时会使用每一个?)

Qua*_*noi 129

简而言之:

NOT IN有点不同:如果NULL列表中只有一个,它永远不会匹配.

  • MySQL,NOT EXISTS效率稍低

  • SQL Server,LEFT JOIN / IS NULL效率较低

  • PostgreSQL,NOT IN效率较低

  • Oracle,所有三种方法都是相同的.

  • 另一点是,如果`table1 .a`包含`NULL`,`EXISTS`查询将不返回此行,但如果`table2`为空则`NOT IN`查询将返回.[NOT IN vs. NOT EXISTS Nullable Columns:SQL Server](http://stackoverflow.com/questions/173041/not-in-vs-not-exists/11074428#11074428) (2认同)
  • @Quassnoi - 呃,好点,得到了错误的方法."NOT EXISTS"将始终返回行,但"NOT IN"仅在子查询未返回任何行时才会返回. (2认同)

Guf*_*ffa 5

如果数据库擅长优化查询,则首先将两个数据转换为接近第三个的数据.

对于像你一样的简单情况,应该有很少或没有区别,因为它们都将作为连接执行.在更复杂的查询,数据库可能无法做出加入出来的not innot existsqueryes.在这种情况下,查询会慢得多.另一方面,如果没有可以使用的索引,连接也可能表现不佳,因此仅仅因为您使用连接并不意味着您是安全的.您必须检查查询的执行计划,以判断是否存在任何性能问题.