使用IN over INNER JOIN进行SQL查询优化

gh9*_*gh9 3 sql t-sql sql-server

鉴于:

表y

  • id int clustered index
  • name nvarchar(25)

表无法承受

  • id int clustered Index
  • name nvarchar(25)

表someFunction

  • 然后一些数学会返回一个有效的ID

相比:

SELECT y.name
  FROM y
 WHERE dbo.SomeFunction(y.id) IN (SELECT anotherTable.id 
                                    FROM AnotherTable)
Run Code Online (Sandbox Code Playgroud)

VS:

SELECT y.name 
  FROM y
  JOIN AnotherTable ON dbo.SomeFunction(y.id) ON anotherTable.id
Run Code Online (Sandbox Code Playgroud)

题:

在对这两个查询进行计时时,我发现在大型数据集中,使用的第一个查询比使用IN第二个查询要快得多INNER JOIN.我不明白为什么有人可以帮忙解释一下.

执行计划

Mar*_*ith 5

一般来说IN,不同之处JOIN在于a JOIN可以返回其他行,其中一行在JOIN-ed表中具有多个匹配项.

从您的估计执行计划可以看出,在这种情况下,2个查询在语义上是相同的

SELECT
        A.Col1
        ,dbo.Foo(A.Col1)
        ,MAX(A.Col2)
        FROM A
        WHERE dbo.Foo(A.Col1)  IN (SELECT Col1 FROM B)
    GROUP BY
        A.Col1,
        dbo.Foo(A.Col1)
Run Code Online (Sandbox Code Playgroud)

SELECT
        A.Col1
        ,dbo.Foo(A.Col1)
        ,MAX(A.Col2)
        FROM A
        JOIN B ON dbo.Foo(A.Col1) = B.Col1
    GROUP BY
        A.Col1,
        dbo.Foo(A.Col1)     
Run Code Online (Sandbox Code Playgroud)

即使副本被引入,JOIN它们也将被删除,GROUP BY因为它只引用左侧表中的列.此外,这些重复的行不会改变结果,因为MAX(A.Col2)不会改变.但是,并非所有聚合都是如此.如果您要使用SUM(A.Col2)(或AVGCOUNT)那么重复项的存在将改变结果.

看来,SQL Server没有任何逻辑骨料,比如区分MAX,如和那些SUM等很可能是扩大了所有的重复再后来他们聚集并简单地做了很多工作.

聚合的估计行数是2893.54针对INvs 28271800for,JOIN但这些估计值不一定非常可靠,因为连接谓词是不可分割的.