与索引相关的NOT逻辑的使用


12

根据Microsoft的有关数据库开发的书,考试70-433:Microsoft SQL Server 2008数据库开发

前导通配符和NOT逻辑都不允许查询优化器使用索引来优化搜索。为了获得最佳性能,应避免使用NOT关键字和前导通配符。

所以我认为是NOT INNOT EXISTS等等

现在关于这个SO问题,我认为@GBN选择的解决方案将违反上面给出的声明。

显然,事实并非如此。

所以我的问题是:为什么?

Answers:


21
  • NOT IN (SELECT ...)并且NOT EXISTS (SELECT .. WHERE correlation..)是“反半联接”。也就是说,基于识别集的操作

  • WHERE NOT (MyColumn = 1) 是一个要求查看所有行的过滤器

有关更多信息,请参见:

编辑:为了完整性

左联接通常表现较差。参见http://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server

该站点指出,在MySQL中,NOT EXISTS没有像其他RDBMS那样得到优化,并且LEFT JOIN更好

在SQL Server中,根据经验,我知道LEFT JOIN的运行不如NOT EXISTS好。您通常还需要DISTINCT来获得与另一个处理步骤相同的结果。


0

我为此使用子选择:

SELECT m* from Main AS m 
    WHERE m.id NOT IN 
        (SELECT m2.id FROM Main AS m2 
           WHERE m2.id IN (...possibly null/empty list goes here...));

当然,如果您的桌子很大,您将需要对此进行分析以检查性能。如果您有其他子句在主查询中过滤结果,则可能需要在子选择中重复它们。但是无论如何,子选择都有一个“ IN”与一个“ NOT IN”,因此可以具有不同的大小结果,并且通常情况下,查询性能很重要,因此在与大表一起使用时分析这种方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.