標籤:
1.盡量避免在WHERE子句中對欄位進行NULL值判斷
在WHERE子句中對欄位進行NULL值判斷會導致引擎放棄使用索引而進行全表掃描。如:
SELECT id FROM t WHERE num IS NULL
可以在num欄位設定預設值0,確保表中 num欄位沒有NULL值,然後這樣查詢:
SELECT id FROM t WHERE num=0
2.盡量避免在WHERE子句中使用!=或<>操作符
在WHERE子句中使用!=或<>操作符將導致引擎放棄使用索引而進行全表掃描。最佳化器將無法通過索引來確定將要命中的行數,因此需要搜尋該表的所有行。
3.盡量避免在WHERE子句中使用OR來串連條件
在WHERE子句中使用OR串連條件,將會導致引擎放棄使用索引而進行全表掃描,如:
SELECT id FROM t WHERE num=10 OR num=20
可以改成:
SELECT id FROM t WHERE num=10UNION ALLSELECT id FROM t WHERE num=20
4.慎用IN和NOT IN
因為IN會使系統無法使用索引,而只能直接搜尋表中的資料。如:
SELECT id FROM t WHERE num in(1,2,3)
對於連續的數值,能用BETWEEN就不要用IN
SELECT id FROM t WHERE num BETWEEN 1 AND 3
5.盡量避免在索引過的字元資料中,使用‘%‘開頭搜尋。
此情況下引擎無法利用索引,如:
SELECT * FROM t WHERE name Like ‘%Jhon%‘
建議使用全文檢索索引。
6.必要時強制查詢最佳化工具使用某個索引
如在WHERE子句中使用參數,也會導致全表掃描。因為SQL只有在運行時才會解析局部變數,但最佳化程式不能講訪問計劃的選擇延遲到運行時,它必須在編譯時間進行選擇。然而,如果在編譯時間簡曆訪問計劃,變數的值還是未知的,因而無法作為索引選擇的輸入項。如下面語句會進行全表掃描:
SELECT id FROM t WHERE num = @num
可以改為強制查詢使用索引:
SELECT id FROM t WITH(INDEX(索引名)) WHERE [email protected]
7.盡量避免在WHERE子句中對欄位進行運算式操作
這將導致引擎放棄使用索引而進行全表掃描。如:
SELECT * FROM t WHERE num/2=100
應該為:
SELECT * FROM t WHERE num=100*2
SELECT* FROM t WHERE SUBSTRING(num,1,4)=‘5678‘
應該為:
SELECT * FROM t WHERE num LIKE ‘5678%‘
SELECT * FROM t WHERE DATEDIFF(yy,num,GETDATE())>21
應該為:
SELECT * FROM t WHERE num<DATEADD(yy,-21,GETDATE())
即任何對列的操作都將導致表掃描,包括資料庫函數、計算運算式等;查詢時要儘可能將操作移至右邊。
SQL Server海量資料查詢代碼最佳化建議