[英]Sql query optimization using IN over INNER JOIN
鉴于:
表y
id int clustered index
name nvarchar(25)
表无法承受
id int clustered Index
name nvarchar(25)
表someFunction
相比:
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
的第二个查询要快得多。 我不明白为什么有人可以帮忙解释一下。
一般来说, IN
与JOIN
不同之处在于, 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)
(或AVG
或COUNT
),则重复项的存在将改变结果。
似乎SQL Server没有任何逻辑可以区分MAX
聚合和SUM
类的聚合,因此它很可能会扩展所有重复项,然后在以后聚合它们并简单地完成更多工作。
被聚合行的估计数量为2893.54
对于IN
VS 28271800
的JOIN
,但这些估计不一定是非常可靠的连接谓词是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.