優秀的索引是SQL Server數據庫性能的關鍵,然而高效的索引都是經過精心設計而成的。眾所周知,主鍵是儲存數據對象的唯一標識,如果數據表中沒有聚簇索引,為了維護主鍵的唯一性,SQL Server數據庫在默認情況下將為主鍵創建聚簇索引(Clustered index),除非用
優秀的索引是SQL Server性能的關鍵,然而高效的索引都是經過精心設計而成的。眾所周知,主鍵是儲存數據對象的唯一標識,如果數據表中沒有聚簇索引,為了維護主鍵的唯一性,SQL Server在默認情況下將為主鍵創建聚簇索引(Clustered index),除非用戶特別指定將索引創建為非聚簇索引(Non-clustered index)。
毫無疑問,我們應當為頻繁訪問的數據創建聚簇索引,當然頻繁訪問的字段應當經過詳細的分析和慎重選擇,并且索引值應當盡可能短。提到創建索引,大家往往首先想到主鍵,但是主鍵的數據并不一定被頻繁訪問,而且很多時候為了保證主鍵的唯一性,主鍵的數值往往不是很短,比如我們經常會選擇全局唯一標識符(GUID)類型作為主鍵的數據類型,唯一標識符的長度一般是16個字節,就長度而言,這種數據類型并不是最理想的聚簇索引選項,在這種情況下,可以為主鍵創建非聚簇索引,因為主鍵值在WHERE語句中用來查詢特定的記錄是非常高效的,創建非聚簇索引可以將查詢的效率再上一個臺階。如果您選擇了整型作為主鍵的數據類型,那就可以考慮將為主鍵生成聚簇索引。
SQL Server 2008為我們提供了另外一種索引——設定過濾條件索引(Filtered index),一個設定過濾條件索引是一個特殊的非聚簇索引,它是某些字段的特定子集。換句話說,設定過濾條件索引是基于一部分選定的字段生成的。比如說,在銷售業績數據表中,分公司所在城市的數據存儲在City字段,如果我們創建一個非聚簇索引,那么所有的分公司所在的城市,都會被納入索引當中。但是如果我們使用設定過濾條件索引,我們就可以只選擇一部分城市被索引,比如北京,上海和廣州,代碼如下:
CREATE NONCLUSTERED INDEX FilteredCities ON Sales(City) WHERE City IN (‘北京’,’上海’,’廣州’) 與常規索引的區別在于,我們使用了WHERE語句來設定我們的過濾條件。假定公司的絕大部分收入都是來自于這三個城市的,那么我們的數據庫查詢會經常訪問到在這三個城市產生的銷售記錄,在這種情況下,設定過濾條件索引會占據較少的磁盤空間,因為只有City字段的數值是北京,上海和廣州的記錄會被索引,這些記錄只是整個銷售數據表格中的一部分。
利用設定過濾條件索引可以提升數據庫的性能,首先,只有被索引到記錄發生變化的時候,才需要重建索引。比如,某一條在北京發生的銷售記錄需要調整,在更新操作之后,索引也要隨之更新,這跟其他的索引是一樣的。但如果發生在西安的銷售記錄發生了變化,無論添加或刪除了多少條記錄,我們之前建立的設定過濾條件索引都是不需要任何操作的,因為只有位于北京、上海和廣州分公司的銷售記錄有影響到這個索引。設定過濾條件索引的另外一個優勢是可以減少磁盤讀寫操作,比如我們要查詢所有北京分公司的銷售記錄,那么使用剛才建立的設定過濾條件索引比常規的非聚簇索引要減少很多不必要的磁盤操作。
為了驗證設定過濾條件索引所帶來的性能優勢,我們進行了對比測試。
首先,我們在VirtualBox虛擬機里安裝Windows Server 2008 R2與SQL Server 2008 R2中文版,順便說一下,我們安裝的都是可以試用180天的試用版,在微軟官方網站可以直接,而且現在試用版也不需要申請序列號了,在安裝過程中可以直接選擇安裝180天試用,就可以直接安裝,這位實驗和學習帶來了不少便利。
我們在數據庫中創建了一個500萬條記錄的銷售數據表,當然,銷售金額都是隨機產生的,而city字段,我們隨機產生1到9這9個不同的數字,然后再根據需要將它們在替換為不同的城市,在這個實驗中,我們把北京、上海和廣州的銷售記錄總比例設定為67%。