2010-01-27 23 views
3

我聽說使用IN子句會傷害性能,因爲它沒有正確使用索引。請參閱下面的示例:是否使用WHERE IN傷害查詢性能?

SELECT ID, Name, Address 
FROM people 
WHERE id IN (SELECT ParsedValue FROM UDF_ParseListToTable(@IDList)) 

使用下面的表格獲取這些結果會更好嗎?

SELECT ID,Name,Address 
FROM People as p 
INNER JOIN UDF_ParseListToTable(@IDList) as ids 
ON p.ID = ids.ParsedValue 

這是否取決於您使用的是哪個版本的SQL Server?如果是的話哪些受到影響?

+2

類似http://stackoverflow.com/questions/761150/how-does-the-in-predicate-work-in-sql – 2010-01-27 20:59:14

回答

5

Yes, assuming relatively large data sets.

它被認爲更好地使用EXISTS大型數據集。我遵循這一點,並注意到我的代碼執行時間有所改進。

根據文章,它與INEXISTS是如何內部化有關。另一篇文章:http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210.aspx

+2

存在使用JOIN運算符,其中IN使用OR運算符。 – mrdenny 2010-01-27 21:47:44

+0

這個答案根本不對。第一個鏈接意味着給定查詢的查詢計劃僅依賴於查詢 - 至少在涉及'in'和'exists'查詢時。這完全是不真實的;像「統計」和「參數嗅探」這樣的東西的存在應該足以看出這個想法與現實不符。第二篇文章很好,但它完全不相關 - 它根本不是在談論性能,而是在討論'not in'中含有空集的混淆語義。 – 2015-01-11 14:42:14

+0

爲了澄清:肯定會有一些情況,「IN」條款不是最理想的,但這不是一般趨勢;並且它沒有正確使用索引的概念不會由此答案所說或所鏈接的任何內容來支持。 – 2015-01-11 17:23:37

0

超過INTable Variable,我認爲正確使用索引會提高查詢性能。

此外,從表名​​看來,它似乎並不像你會有很多條目,所以在這個特定的例子中,你走哪條路可能是沒有意義的。

其次,IN將僅被評估一次,因爲沒有子查詢。在你的情況下,@ IDList變量可能會導致你需要的錯配匹配@IDList1, @IDList2, @IdList3....,因爲IN需要一個列表。

作爲一般的經驗法則,您應該避免使用IN進行子查詢,並使用EXISTS進行加入 - 您會獲得更好的性能。

0

IN會傷害性能,因爲SQL Server必須生成一個完整的結果集,然後根據結果集中的行數創建一個巨大的IF語句。順便說一句,調用UDF也可能是一個真正的性能問題。他們非常好用,但如果你不小心,可以真正影響性能。您可以通過Google UDF和Performance對此進行一些研究。

0

您的第一個示例與第二個示例不同,因爲WHERE X IN (@variable)WHERE X = @variable相同(即您不能具有變量列表)。

關於性能,您必須查看執行計劃以查看選擇了哪些索引。

+0

我看着我的原始查詢,並想我明白你在說什麼。看看我的更新 – 2010-01-27 21:44:24

+0

@AbeMiessler你的版本之間仍然存在語義上的差異。如果列表中有重複項,則會在第二個項中導致交叉連接效果。所以這在理論上應該對執行計劃有一個小的影響,但如果列表很小(第一個案例計劃可能與第二個案例計劃可能與第二個案例計劃相同,以獲得不同的列表),則可能並不重要。我的錢將近乎類似的執行計劃。 – 2010-01-28 14:42:59

2

找到它非常簡單 - 打開Management Studio,將兩個版本的查詢放入,然後在打開顯示執行計劃的情況下運行。比較兩個執行計劃。通常(但並非總是),查詢優化器會爲邏輯上等效的查詢的不同版本制定相同的確切計劃/從字面上做相同的事情。實際上,這就是它的目的 - 目標是優化器將採用任何版本的查詢,假設邏輯相同,並制定最佳計劃。 唉,這個過程並不完美。

這裏有一個科學的比較:

http://sqlinthewild.co.za/index.php/2010/01/12/in-vs-inner-join/ http://sqlinthewild.co.za/index.php/2009/08/17/exists-vs-in/