簡體   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