SQL SERVER索引原理及填充因子

SQL SERVER索引原理及填充因子

在SQL Server中,索引是按B樹(平衡樹)結構進行組織的,索引B樹中的每一頁稱為一個索引節點,B樹的頂端節點稱為根節點,索引中的底層節點稱為葉節點,根節點與葉節點之間的任何索引級別統稱為中間級,當加入新的數據時,為了保證需要相同次數的讀取來找到每個頁,中間級頁會進行拆分生成新的層,如圖所示。

SQL SERVER索引原理及填充因子

每個層的寬度增加為上一層能夠記錄的頁數,當現有的樹不能記錄更多的頁時,則會創建一個新的層,索引記錄的大小受到編入索引列的大小影響,因此編入索引列越窄,則可以放到一個頁的索引越多,從而索引需要的層數越少,每一層需要1次邏輯讀,所以索引樹層次越少越好。

填充因子是指每個葉子層頁填充數據的百分比,提供填充因子選項是為了優化索引數據存儲和性能,使用fill factor選項可以指定Microsoft SQL Server使用現有數據創建新索引時將每頁填滿到什麼程度。fill factor選項是一個高級選項,如果使用sp_configure系統存儲過程來更改該設置,則只有在show advanced options設置為1時才能更改fill factor,設置在重新啟動服務器後生效。

當創建或重新生成索引時,填充因子值可確定每個葉級頁上要填充數據的空間百分比,以便保留一定百分比的可用空間供以後擴展索引。例如,指定填充因子的值為80表示每個葉級頁上將有20%的空間保留為空,以便隨著在基礎表中添加數據而為擴展索引提供空間。

填充因子可設置值為1到100之間的一個百分比,在大多數情況下,服務器範圍的默認值為0,如果將填充因子設置為0,則表示填充滿整個葉級頁,但在實際測試過程中一般不會設置為填充滿葉級頁,因為至少需要留出再添加一個索引行的空間,使用此設置可有效使用葉級空間,但應保留一定的空間以便在不得不拆分頁之前進行有限的擴展。

注意:填充因為設置為0和設置為100含意相同,都表示填充滿整個葉級頁。並且只有在創建或重新生成了索引後,才會應用填充因子,SQL Server Database Engine 並不會在頁中動態保持指定的可用空間百分比,如果試圖在數據頁上保持額外的空間,將有背於使用填充因子的本意,因為隨著數據的輸入,數據庫引擎將不得不在每個頁上進行頁拆分,以保持填充因子所指定的可用空間百分比。

如果向已滿的索引頁添加新行,數據庫引擎將把大約一半的行移到新頁中,以便為該新行騰出空間,這種重組稱為頁拆分。頁拆分可為新記錄騰出空間,但是執行頁拆分可能需要花費一定的時間,此操作會消耗大量資源。此外,它還可能造成碎片,從而導致I/O操作增加,這樣會直接影響數據庫的性能。正確選擇填充因子值可提供足夠的空間以便隨著向基礎表中添加數據而擴展索引,從而減少頁拆分可能性。如果經常發生頁拆分,可通過使用新的或現有的填充因子值來重新生成索引,從而重新分發數據。

儘管採用較低的填充因子值(非0)可減少隨著索引增長而拆分頁的需求,但是索引將需要更多的存儲空間,並且會降低讀取性能,即使對於面向許多插入和更新操作的應用程序,數據庫讀取次數一般也超過數據庫寫入次數的5到10倍。因此,指定一個不同於默認值的填充因子會降低數據庫的讀取性能,而降低比與填充因子設置的值成反比。例如,當填充因子的值為50時,數據庫的讀取性能會降低兩倍,讀取性能降低是因為索引包含較多的頁,因此增加了檢索數據所需的磁盤I/O操作。


分享到:


相關文章: