[英]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.