SARG 簡易筆記
SARG 意義:在查詢子句中,SARG 代表用來搜尋的常數或變數可以直接與索引鍵值做比較
SARG 運算子列表
- 符合:=、<、>、>=、<=、BETWEEN、LIKE (看 % 位置)
- 不符合:NOT、!=、<>、!>、!<、NOT EXISTS、NOT IN、NOT LIKE
SARG 格式理論物流申請例子來說明,商業邏輯很簡單,Transport 是物流申請資料,Car 是派車資料檔頭、CarDetail 則是 Transport 資訊和數量,Transport 資料是可以存在多張派車單內,所以要知道待運送的 Transport 資料,必須用下述語法去比對出來
- 符合:
- 資料欄位 符合 SARG 運算子 <常數或變數>
- <常數或變數> 符合 SARG 運算子 資料欄位
- 不符合:資料欄位 運算子 資料欄位
SELECT
T.*
, D.TranNO
, ISNULL(D.TranQty, 0) AS TranQty
FROM Transport AS T
LEFT JOIN
(
SELECT
TranNO
, SUM(TranQty) AS TranQty
FROM CarDetail
GROUP BY TranNO
) AS D ON T.TranNO = D.TranNO
WHERE (D.TranNO IS NULL
OR T.Qty > D.TranQty)
當時這樣設計看執行 Statistics 覺得很 OK、還覺得執行計劃有跑出平行處理很不錯,時過境遷後,現在看到平行處理就覺得事情不尋常,Orz
醜醜的執行計畫,通通從 Transport 和 CarDetail 跑 Clustered Index Scan 來處理
有該篇 - [SQL] 利用 UNION ALL 取代 OR 條件 經驗,當然是要來嘗試一下
SELECT T.* , 0 AS TransQty FROM Transport AS T WHERE NOT EXISTS ( SELECT 1 FROM CarDetail AS D WHERE T.TranNO = D.TranNO ) UNION ALL SELECT T.* , D.TranQty FROM Transport AS T JOIN ( SELECT TranNO , SUM(TranQty) AS TranQty FROM CarDetail GROUP BY TranNO ) AS D ON T.TranNO = D.TranNO WHERE T.Qty > D.TranQty
改完之後發現更慘,Statistics 為原本兩倍左右,執行計畫也肥了不少
無法從語法獲得改善,就只能動 Table Schema 來改善囉
沒有留言:
張貼留言