繁体   English   中英

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

[英]Sql query optimization using IN over INNER JOIN

鉴于:

表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)

VS:

SELECT y.name 
  FROM y
  JOIN AnotherTable ON dbo.SomeFunction(y.id) ON anotherTable.id

题:

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

执行计划

一般来说, INJOIN不同之处在于, 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)

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)     

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

似乎SQL Server没有任何逻辑可以区分MAX聚合和SUM类的聚合,因此它很可能会扩展所有重复项,然后在以后聚合它们并简单地完成更多工作。

被聚合行的估计数量为2893.54对于IN VS 28271800JOIN ,但这些估计不一定是非常可靠的连接谓词是unsargable。

你的第二个问题有点好笑 - 你可以试试这个吗?

SELECT y.name 
FROM dbo.y
INNER JOIN dbo.AnotherTable a ON a.id = dbo.SomeFunction(y.id) 

这有什么不同吗?

否则:看看执行计划! 并可能在这里发布。 如果你不了解更多关于你的表(数据的数量和分布等)和你的系统(RAM,磁盘等),真的很难给出一个“全局”有效的声明

好吧,首先:摆脱dbo.SomeFunction(y.id)隐含的标量UDF。 那将会扼杀你的表现 即使用一行内联表值函数替换它也会更好。

至于你的实际问题,我在其他情况下也发现了类似的结果,也同样感到困惑。 优化器只是区别对待它们; 我很想知道其他人提供的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM