下述 TSQL where 條件,對 ModifiedDate 欄位進行函數轉換,從執行計畫就可以觀察到跑 clustered index scan
基本上還是推薦 TSQL 語法也要一併改寫的作法
SELECT
BusinessEntityID ,
ModifiedDate
FROM Person.Person
WHERE (CAST(YEAR(ModifiedDate) AS varchar(4))
+ RIGHT(REPLICATE('0' , 2) + CAST(MONTH(ModifiedDate) as varchar(2)) ,2))
= '200901'
建立計算欄位 (YYYYMM) 和對應的 Index 來改善該情況
ALTER TABLE Person.Person ADD YYYYMM AS
(CAST(YEAR(ModifiedDate) AS varchar(4))
+ RIGHT(REPLICATE('0' , 2) + CAST(MONTH(ModifiedDate) as varchar(2)) ,2))
PERSISTED
CREATE INDEX IX_Person_YYYYMM ON Person.Person (YYYYMM)
實際執行下述兩個 where 條件,都會觸發 IX_Person_YYYYMM index seek-- 修正 where 條件,改以計算欄位為搜尋條件
SELECT
BusinessEntityID ,
ModifiedDate
FROM Person.Person
WHERE YYYYMM = '200901'
-- 維持原本 where 條件
SELECT
BusinessEntityID ,
ModifiedDate
FROM Person.Person
WHERE (CAST(YEAR(ModifiedDate) AS varchar(4))
+ RIGHT(REPLICATE('0' , 2) + CAST(MONTH(ModifiedDate) as varchar(2)) ,2))
= '200901'
最後來測試不同日期轉換方式,是否也能觸發 IX_Person_YYYYMM index seek
SELECT
BusinessEntityID ,
ModifiedDate
FROM Person.Person
WHERE convert(varchar(6) , ModifiedDate , 112)
= '200901'
從執行計畫就可以發現完全沒有使用 IX_Person_YYYYMM
基本上還是推薦 TSQL 語法也要一併改寫的作法