2011-09-12 56 views
2

我遇到以下情況:爲什麼IN語句中的項目列表比IN語句中的子查詢更快?

我有一個相當複雜的視圖,我必須從中選擇一對記錄。

SELECT * FROM VW_Test INNER JOIN TBL_Test ON VW_Test.id = TBL_Test.id 
WHERE VW_Test.id IN (1000,1001,1002,1003,1004,[etc]) 

這實際上會立即返回結果(當前在該IN語句中有25個項目)。但是,當我使用以下查詢時,速度非常快。

SELECT * FROM VW_Test INNER JOIN TBL_Test ON VW_Test.id = TBL_Test.id 
WHERE VW_Test.id IN (SELECT id FROM TBL_Test) 

在TBL_Test中有25條記錄,這個查詢大約需要5秒。我在TBL_Test中找到了該ID的索引。

任何人都知道爲什麼發生這種情況以及如何獲得性能?

編輯:我忘了提,這個子查詢

SELECT id FROM TBL_Test 

返回結果立即爲好。

+0

「TBL_Test」上的統計信息是否爲最新?請比較執行計劃,看看它們之間有什麼不同。這是你的實際查詢還是你簡化了它?不知道您是否可能在子查詢中使用了不可更改的過濾器,從而導致統計數據估計錯誤。 –

+0

@Kirill該查詢執行完全相同。 – SouthL

+0

@Martin執行計劃之間的區別似乎是,它在第​​一個過濾視圖很快。當我使用子查詢時,它會拉起整個視圖,然後將它與TBL_Test連接起來 – SouthL

回答

1

那麼,當使用子查詢時,數據庫引擎首先必須爲子查詢生成結果,然後才能執行其他任何操作,這需要花費時間。如果你有一個預定義的列表,這不需要發生,引擎可以簡單地使用這些值。至少,這是我的理解。

如何提高性能:取消子查詢。在這種情況下,我認爲你甚至不需要IN子句。 INNER JOIN應該就足夠了。

+0

我不明白的是從子查詢中獲取結果也是瞬間的;我忘了在我的問題中提到這一點。我會在編輯 – SouthL

+0

@Frank'IN'被實現爲(半)參加在SQL Server –

+0

@馬丁,我認爲弗蘭克的一點是,IN是完全沒有必要的,但是 - 給定的查詢應該返回一模一樣結果,如果你只是完全刪除它的WHERE子句。 –