SQL Server評價索引之有效性
以下的文章主要描述的是SQL Server評價索引之有效性(Evaluating Index Usefulness),SQL Server數據庫所提供的索引主要有2個原因:***是作為一種保證數據庫表中數據唯一性的方法;其二,提供了一種快速訪問表中數據的方法。
創建合適的索引是數據庫物理設計時最為重要的方面之一。因為你不能在一個表上無限制地創建索引,而且不管怎么說,它也是不可行的。所以,你將想在一些具有高選擇性 (high Selectivity )的列上創建索引,這樣,查詢時系統將會利用這些索引。一個SQL Server評價索引的選擇性定義如下:
引用
選擇率 = (唯一索引值的個數)/ (表中所有行數)
- Selectivity ratio = (Number of unique index values)/ (Total number of rows in the
如果選擇率高——也就是說,大量行都可以用索引鍵值來唯一標識——那么該SQL Server評價索引就具有高選擇性,即對優化器來說也是有用的。***的選擇性是1,即每一行都有一個唯一的索引鍵值。低選擇性意味著表中有許多重復的鍵值,這樣的索引將很少有用。
SQL Server優化器基于索引的選擇性來決定對一個查詢是否使用索引。越高的選擇性,SQL Server檢索結果集(Result set)就越快和越有效。
例如,你正在對authors 表中的索引的有效性進行評估。假如大多數查詢是以author's last name或者state來進行訪問的。因為大量的并發用戶會修改該表的數據,你只允許一個索引——author's last name或者state,你將會選擇誰?讓我們進行一些分析來判斷哪個索引更有效些,或者更有選擇性。首先,利用一個查詢來確定pubs數據庫中 author表的last name列的有效性:
Sql代碼
- select count(distinct au_lname) as '# unique',
- count(*) as '# rows',
- str(count(distinct au_lname) / cast (count(*) as real),4,2) as 'selectivity'
- from authors
- go
- select count(distinct au_lname) as '# unique',
- count(*) as '# rows',
- str(count(distinct au_lname) / cast (count(*) as real),4,2) as 'selectivity'
- from authors
- go
- # unique # rows selectivity
- 22 23 0.96
author表的au_lname列的有效率計算值為0.96,表明在au_lname創建的SQL Server評價索引將具有高選擇性,也是一個好的候選索引。除了一行外,其余所有行的last name值都唯一。 現在,來分析state列的選擇性:
Sql代碼
- select count(distinct state) as '# unique',
- count(*) '# rows',
- str(count(distinct state) / cast (count(*) as real),4,2) as 'selectivity'
- from authors
- go
- select count(distinct state) as '# unique',
- count(*) '# rows',
- str(count(distinct state) / cast (count(*) as real),4,2) as 'selectivity'
- from authors
- go
- # unique # rows selectivity
- 8 23 0.35
正如你所看到的,state列的SQL Server評價索引選擇率(0.35)比au_lname索引選擇率要低很多,將不太有用。
對于這一點,你可能會問,是否因為state列中的一些值具有較高的重復性而導致了選擇性的下降,或者說僅僅只有一些值具有唯一性。你可以用下面的查詢來確定:
Sql代碼
- select state, count(*)
- from authors
- group by state
- order by 2 desc
- go
- select state, count(*)
- from authors
- group by state
- order by 2 desc
- go
- state
- CA 15
- UT 2
- TN 1
- MI 1
- OR 1
- IN 1
- KS 1
- MD 1
正如你所預料到的,state值,除了一個外,其余值都相對唯一。因為表中有多一半的state值都為‘CA’。所以state可能不是一個好的候選索引列,特別是假如大部分時間你都以CA來進行查詢,此時,SQL Server將發現掃描整個表將比借助索引進行查詢數據更有效。
一般來說,如果一個鍵值的選擇率低于0.85,那么優化器通常會選擇表掃描來處理查詢。在這種情況下,使用表掃描來獲取所有滿足條件的數據行將比通過B-Tree來定位大量數據行來查找更有效率。
如果有更多的索引可以選擇,那么SQL Server將怎樣來確定每個索引是否具有選擇性和到底選擇哪一個索引對用戶來說更有效呢?例如,SQL Server怎么知道下面的索引能夠返回多少行?
- select * from table where key between 1000000 and 2000000
如果該表在0到20,000,000之間有10,000,000行記錄,優化器如何知道是使用一個索引還是進行表掃描呢?如果在該范圍內有10行記錄,或者900,000,又如何選擇?SQL Server如何來估計在1,000,000 至2,000,000之間有多少行?等等諸如此類的問題,優化器是從SQL Server評價索引統計(Index Statistics)中獲得這些信息的。
【編輯推薦】
- SQL Server 實用操作的代碼演示
- SQL Server 2005數據庫安裝實例演示
- SQL Server 2005 Express混合模式登錄的設置
- SQL Server數據庫在安裝時的注意事項
- SQL Server Compact中的DLL文件與工具