SQL Server優化篇:過濾條件設定提高索引效率

來源:互聯網
上載者:User
關鍵字 網路程式設計 Mssql教程

設定過濾條件提高索引效率

優秀的索引是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%。

接下來,我們將虛擬機器進行完整的複製,這樣就可以得到兩套完全一致的作業系統和資料庫,資料庫中已經包含了我們剛剛創建的資料表,相關過程可以參考VirtualBox的技術文檔。 複製整個虛擬機器的目的在於確保硬體和作業系統對資料庫性能的影響最小,以便於我們將注意力集中在不同索引方式下,資料庫性能的表現。

下一步,我們在第一個虛擬機器中創建city欄位的完整的非聚簇索引,代碼如下:

CREATE NONCLUSTERED INDEX FilteredCities ON Sales(City)
在第二個虛擬機器中,我們創建設定過濾條件索引,代碼如下

CREATE NONCLUSTERED INDEX FilteredCities ON Sales(City)  WHERE City IN ('北京','上海','廣州')

然後我們在兩個虛擬機器的資料庫中來計算北京、上海和廣州這三個城市的銷售金額總和,代碼如下

SELECT SUM(Value) FROM Sales  WHERE City = '北京' or City = '上海' or City = '廣州'
在使用完整的非聚簇索引的情況下,我們花費了27秒,而使用設定過濾條件索引的情況下,我們只需要14秒就得到了計算結果,可見非聚簇索引在大規模資料計算的情況下,對性能的提升還是非常可觀的,我們截取的螢幕如下,供大家參考:

在選擇過濾條件的時候,我們需要考慮哪些資料會隨著時間的推移而經常變化,比如,新增加的記錄是添加到索引的中間還是末尾? 當記錄刪除的時候,索引值是否需要隨之刪除? 這些問題的答案都會影響我們對索引的設計。

在這裡,我們需要用到填滿因數(Fill Factor),填滿因數是一個以百分比表示的數值,在重建索引的時候,填滿因數的值決定了每個頁面上要填充資料的空間百分比,以便保留一些剩餘空間作為以後擴展索引的可用空間, 以下代碼演示了如何將填滿因數設定為80,只有在高級選項打開的情況下才能設定填滿因數:

Use DatabseName;  GO  sp_configure 'show advanced options', 1;  GO  RECONFIGURE;  GO  sp _configure 'fill factor', 80;  GO
如果填滿因數的值是100,那麼索引頁就被會全部填充。 我們一般考慮將填滿因數設定為50到80中間的數值來保證添加新值的時候,不會發生頁拆分。 如果經常需要在索引末尾添加欄位值的話,可以考慮將填滿因數設定為90到100之間的值。 最理想的狀態是同時保證最少次數的的頁拆分和索引重建
 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.