Sql-Server
SQL Server - 連接中的子查詢與不連接
我的應用程序在各種表中都有巨大的記錄集(> 10 億條記錄),並且在閱讀了多篇相互矛盾的文章時想知道更好的方法。問題是性能更好(內部連接)
- 加入表,然後在 where 子句中過濾
- 加入過濾記錄的子查詢
例子
Select T1.Id from Table1 T1 inner join Table2 T2 on T1.JoinId = T2.T1JoinId where T1.RefId = 1
VS
Select T1.Id from (select Id,T1JoinId from Table1 where RefId = 1) T1 inner join Table2 T2 on T1.JoinId = T2.T1JoinId
我的理解是在第二種情況下執行計劃會更快,但在性能方面,它與實際計劃相同
你基本上是在問,“連接兩張桌子最快的方法是什麼?”
答案將取決於很多事情,甚至取決於 SQL Server 在優化查詢時需要花費多少時間。
您最好的選擇是雙向執行查詢並進行比較,而不是問一個一般的理論問題:
- SET STATISTICS IO ON 的輸出,它將每個表的讀取次數放在 SSMS 的 Messages 選項卡中
- SET STATISTICS TIME ON 的輸出,它也將 CPU 時間量和總持續時間放在消息選項卡中(但請注意,這在傳遞之間可能會有很大差異,具體取決於當時伺服器上發生的其他活動)
- 實際(非估計)執行計劃,其中可能包含其他詳細資訊,例如哪個計劃溢出到磁碟或遇到計劃優化超時
我完全同意布倫特,只是想補充幾點:
優化器有一堆轉換規則。即,一種表述某事的方式可以轉化為另一種方式。在優化階段的早期,就會應用這些規則。
您不應該假設該計劃類似於查詢中事物的“順序”,包括子查詢。換句話說,在大多數情況下,您會發現您的兩個查詢生成相同的計劃。
相同的計劃是否意味著相同的性能?是的,在很大程度上。直到您的編譯時間與執行時間相比顯著增加*,並且*您的一個查詢的編譯時間明顯更短。我有一種感覺,如果您對編寫的每個查詢都進行盡職調查,那麼在遇到存在顯著差異的奇怪情況之前,您會因為沒有看到任何(或可能只有很小的)性能差異而感到疲倦。