sql server 資料庫優化--顯示執行計劃 你真的知道索引使用???
首先在PRID欄位上建立非聚集索引。
CREATE UNIQUE NONCLUSTERED INDEX UNC_PRID |
執行下面語句並檢視執行計劃的結果。
Select PRID, PRCode, PRDesc |
奇怪了,“Table Scan”仍然用到了。為什麼SQL Server沒有用到那個非聚集索引?於是繼續優化查詢語句,選擇檢索兩個欄位 [PRID, PRCode] 。
Select PRID, PRCode From PerformanceIssue |
執行結果是和上一個查詢結果一摸一樣。於是修改查詢為只檢索一個欄位 [PRID] 。
Select PRID |
執行計劃結果如下:
“Index Scan”在查詢中被用到了,這很好。很自然,接下來的問題就是“Index Scan”什麼時候會被用到。欄位PRID上有一個索引,查詢語句中選中的欄位為PRID。執行查詢的時候,SQL Server掃描索引頁,因此用到了“Index Scan”方法。前面的查詢中選擇了有索引的和沒有索引的欄位,SQL Server無法使用“Index Scan”。當查詢中只選擇有索引的欄位時,SQL Server就使用了“Index Scan”。我不清楚SQL Server底層到底是如何判斷的,不過通過這些試驗,我認為當查詢中只選擇有索引的欄位時,SQL Server就使用“Index Scan”方法
下面看“Index Seek”方法何時產生。當我看到“Seek”這個詞時,第一反應就是條件查詢這個主意。
我嘗試三種不同的帶WHERE語法的查詢語句,以找出那種會用“Index Seek”。第一種語句如下:
Select PRID, PRCode, PRDesc |
結果顯示,執行計劃使用了“Table Scan”。
第二種語句如下:
Select PRID, PRCode, PRDesc |
執行計劃仍然使用“Table Scan”方法。
第三種查詢語句如下:
Select PRID, PRCode, PRDesc |
查詢用到了“Index Seek”和“Bookmark Lookup”方法。用到“Index Seek”是因為WHERE後面使用帶索引的欄位PRID來進行過濾。“Bookmark Lookup”方法被用到是因為查詢中選擇了沒有索引的欄位。如果去掉這兩個沒有索引的欄位,那麼“Bookmark Lookup”方法就可以去掉。當然如果只返回PRID欄位,那麼該查詢就沒什麼意義了,因為WHERE語句後面已經給出PRID具體取值了。
我認為“Index Seek”在效能改善上比“Index Scan”和“Table Scan”要好,這主要表現在下面幾個方面:
- “Index Seek”不需要對錶和索引頁進行掃描;而“Table Scan”和“Index Scan”需要。
- “Index Seek”利用“WHERE”來過濾獲取的資料,這樣比用“Index Scan”和“Table Scan”快很多。
當我完成這些測試後,我同事問我一個很有意思的問題:SQL Server什麼時候使用“Clustered Index Scan”和“Clustered Index Seek”?下面對“Clustered Index Scan”和“Clustered Index Seek”進行實驗。
我決定在PRCode上建一個聚集索引來測試“Clustered Index Scan”和“Clustered Index Seek”。