2017-03-07 71 views
-2

我有一個表(我們稱之爲A)SQL Server 2016中,我想查詢。我只需要選擇那些具有確定狀態的行,所以我需要排除一些行。還有另一個表(B),其中包含來自表A的記錄ID和兩列col1和col2。如果這些列是非空的,則相應的記錄可以被認爲是最終的。表A和表B之間存在一對一的關係。由於這些表非常大,我想使用最有效的查詢。我應該選擇哪一個?哪個是運行此SQL查詢最快的方法?

SELECT * 
FROM TableA 
WHERE record_id IN 
    (SELECT record_id FROM TableB WHERE col1 IS NOT NULL AND col2 IS NOT NULL) 

SELECT a.* 
FROM TableA a 
INNER JOIN TableB b ON a.record_id = b.record_id 
WHERE b.col1 IS NOT NULL AND b.col2 IS NOT NULL 

SELECT a.* 
FROM TableA a 
INNER JOIN TableB b 
ON a.record_id = b.record_id 
    AND b.col1 IS NOT NULL 
    AND b.col2 IS NOT NULL 

當然,如果有更快的方式,我沒有想到,請分享。我也很想知道爲什麼一個查詢比其他查詢更快。

+2

請閱讀Eric Lippert的優秀[哪個更快?](https://ericlippert.com/2012/12/17/performance-rant/):「...如果你有兩匹馬,你想知道哪些二者之間的距離越大,你的馬匹的速度越快,不要寫簡短的馬匹描述,在互聯網上發佈,並要求隨機的陌生人猜猜哪個更快......「 –

+2

爲什麼你不試試它並找到出來嗎? –

+0

我做過了,但結果各不相同。差異是相當顯着的(〜20%),但更快的查詢並不總是一樣的... –

回答

0
WITH cte AS 
(SELECT b.record_id, b.col1, b.col2 
FROM TableB b 
WHERE col1 IS NULL 
AND col2 IS NULL --if the field isn't NULL, it might be quicker to do <> '') 

SELECT a.record_id, a.identifyColumnsNeededExplicitely 
FROM cte 
JOIN TableA a ON a.record_id = cte.record_id 
ORDER BY a.record_id 
+0

CTE爲什麼要在這裏提高性能? –

+0

實際上,您可能需要考慮執行此查詢FROM tableA而不是FROM cte。這應該使它更快; CTE允許表(已過濾)存儲在mem中(最重要的是,只能讀取一次),從而使查詢更快。下一步,使用執行計劃,索引/重新索引無效的表。 – WickedFan

0

在實踐中的執行計劃將盡一切取決於你的當前索引/聚集索引/外鍵/約束/統計中的表(又名行數的行/一般containt/...)喜歡。任何分析都應該逐案進行,2個表格的真實情況可能不適用於其他2個表格。

Theorically,

沒有任何索引,第一個應該是最好的,因爲它將使上操作的優化與表B 1次表掃描,2個contants掃描上表B和表1 1個表掃描。

使用TableA.record_id上的外鍵引用TableB.record_id或兩列中的索引時,第二個應該更快,因爲它將使掃描索引和2恆定掃描。

在極少數情況下,它可能是第三種,具體取決於TableB統計信息。但是從數字2開始不遠,因爲數字3將掃描所有TableB。

在更爲罕見的情況下,既不的3

什麼我tryng說的是:「既然我們沒有沒有你的表也不行,打開你的SQL管理,把統計ON和自己嘗試一下。「