過濾加入條件和性能
我有以下類型的查詢:
SELECT * FROM CUSTOMER C JOIN USERTABLE U on C.AccountmanagerID = US.ID
user 表也有外部使用者,這些使用者永遠不能是 accountmanager。該表有大約 30k 條記錄,其中只有大約 500 個使用者可以是 accountmanager。我可以根據使用者名的長度過濾它們。僅返回 1k 條記錄。
SELECT * FROM CUSTOMER C JOIN USERTABLE U on C.AccountmanagerID = US.ID AND len(U.USERNAME) = 3
當我執行查詢計劃時,第二個查詢計劃效率更高,我可以想像,但我找不到任何完整的理由。有人可以啟發我並給我一些背景資訊。我也想知道這是否總是如此,或者這只是巧合。
查詢計劃連結: https ://www.brentozar.com/pastetheplan/?id=HypDy3MnP
提前致謝
不同之處在於您的第二個
Execution Plan
是在您的 Customer 表上使用 Index Seek (這通常是一個性能更高的操作):這是因為您的附加過濾器會導致 a
cardinality
返回更少的記錄,並使Index Seek
操作比Index Scan
. 請注意第一個執行計劃和第二個執行計劃中箭頭之間的粗細差異。JOIN
由於第二個查詢的謂詞有助於預先過濾數據,因此第二個計劃中返回的行數要少得多。這也導致
JOIN
對兩者Tables
一起使用更有效的操作,使用Nested Loops
運算符而不是Merge Join
.要回答您的最後一個問題,這既不是巧合,也不是總是如此,
Execution Plans
而且 SQL 引擎在後台所做的工作相當複雜,因此測試和比較計劃和結果是了解正在發生的事情的最佳方式,因為推測對於給定的場景是困難的,並且從一個場景到下一個場景都不同。在這種情況下,它剛剛發現您選擇的過濾器預先從 User 表中減少了足夠的記錄,
INNER JOIN
到 Customer 表要小得多,並允許它使用Index Seek
性能更高的操作(並且再次導致JOIN
操作也是一種更有效的東西,一種Nested Loops
操作)。當您在“OSUSR_6VB_MSS_CUSTOMER”中突出顯示操作時
JOIN
,您可以通過查看“估計行數”(在這種情況下,您應該使用Actual Execution Plan
而不是Estimated Execution Plan
盡可能)屬性來查看客戶表中記錄的減少。Index Scan
第一個Execution Plan
與Index Seek
第二個中的操作Execution Plan
相比,從 31,877 行變為大約 472 行: