SQL Server索引覆蓋的實際應用代碼描述
以下的文章主要向大家講述的是SQL Server索引覆蓋(Index Covering),SQL Server數據庫索引覆蓋主要是這種情況,查詢中的select 與where子句中所需要的信息都能在非聚集索引中找到。
因為非聚集索引包含了一個對應于表中每個數據行的一個葉子行,SQL Server能從非聚集索引的葉子行來滿足查詢。這導致了數據檢索的更快,因為所有的信息能從索引頁中直接獲得,并且避免了SQL Server查找數據頁。
因為非聚集索引的葉子頁都連接在一起,索引的葉級可以像表中的數據頁一樣進行掃描,因為頁級行都典型比數據行要小,一個覆蓋了查詢的非聚集索引將比同樣列的聚集索引更快,因為需要讀取的頁數要更少。
在下面的例子中,quthors表中的關于au_lname 和au_fname的非聚集索引將覆蓋查詢,因為結果中的列和SARG都能從索引中提取出來:
- Sql代碼
- Select au_lname, au_fname
- From authors
- Where au_lname like "M%"
- GO
- Select au_lname, au_fname
- From authors
- Where au_lname like "M%"
- GO
其他使用聚合函數(MIN AVG SUM COUNT)的查詢或者僅僅檢查是否存在的查詢也能從SQL Server索引覆蓋中獲益。下面是一些能夠利用索引覆蓋優點的查詢:
- Sql代碼
- Select count (au_lname) from authors where au_lname like 'm%'
- Select count (*) from authors where au_lname like 'm%'
- Select count (*) from authors
- Select count (au_lname) from authors where au_lname like 'm%'
- Select count (*) from authors where au_lname like 'm%'
- Select count (*) from authors
你可能會奇怪最后一個查詢,它甚至沒有一個具體的SARG,怎么還能使用索引。SQL Server知道非聚集索引的特性,一個非聚集索引為表中的每行數據都包含了一行;它能夠簡單的計算任何一個非聚集索引的行數,而不需要掃描整個表。對最后一個查詢,SQL Server選擇最小的非聚集索引——也就是,具有最少的葉子頁的索引。
向非聚集索引添加列使得發生SQL Server索引覆蓋是一種提高查詢響應時間的常見方法。考慮下面的查詢:
- Sql代碼
- Select royalty from titles
- Where price between $10 and $ 20
- Select royalty from titles
- Where price between $10 and $ 20
如果你僅在price列上創建索引,SQL Server能發現滿足price在該范圍的索引中的行,但是它還需要訪問數據行來檢索royalty。范圍中有100行,最壞情況下檢索數據所花費的IO代價計算如下:
引用
索引的級數
+查找匹配行的索引頁的數
+100 * 每個書簽查找頁數
如果royalty列添加到了price列索引中了,索引能被掃描來檢索結果,而不是進行書簽查找,這樣具有更快的查詢響應。使用SQL Server索引覆蓋的IO代價將只是:
引用
索引級數
+查找匹配行的索引頁的數
引用
注意:
當考慮添加索引來利用索引覆蓋時,小心使得索引變得太寬。當索引行的寬度接近與數據行寬度時,覆蓋的優點將失去,因為增加了葉級頁的數目。當索引的葉級頁的數目接近了表中頁的數目,索引級數也增加了,那么索引掃描的時間就開始接近于表掃描時間了。
另外,如果你添加對到索引中的列頻繁修改,數據行中列的任何修改也會波及到索引中。這增加了維護的負擔,也會影響修改的性能。
正如第33章討論的那樣,當在一個表上創建了 一個聚集索引,聚集鍵會被所有的非聚集索引引用,作為書簽來定位實際的數據行。聚集鍵實際就是一些列,它們構成了聚集索引和它們的數據值。這種特性有時也能導致SQL Server索引覆蓋。
例如,假設suthors表在au_lname au_fname列上建立聚集索引,并有一個定義在au_id的非聚集索引。非聚集索引的每行都包含了與數據行對應的au_lname au_fname聚集鍵值。因為這個原因,下面查詢將被非聚集索引覆蓋:
- Sql代碼
- select au_lname, au_fname
- from authors
- where au_id like '123%'
以上的相關內容就是對SQL Server索引覆蓋(Index Covering)的介紹,望你能有所收獲。
【編輯推薦】