首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 索引優化實戰:填充因子 完整指南

     編輯:關於SqlServer

什麼是填充因子?

Fill Factor (填充因子):指定索引葉層頁面資料充滿度百分比 (0-100)。僅在建立/重建索引時生效,預留空間減少未來插入導致的頁面分裂。

  • 0 或 100:頁面完全填滿 (預設)。
  • 60:頁面僅填 60%,保留 40% 空間供後續插入/更新展開。

填充因子示意圖

運作機制

  1. 建立索引時依指定百分比填滿葉頁,剩餘空間留白。
  2. 後續 INSERT/UPDATE 導致鍵值需插入頁面中間時,若有預留空間 → 就地插入,無頁面分裂。
  3. 若無預留空間 (100%) → 頁面分裂:約一半資料移至新頁,產生碎片、增加 I/O、降低效能。
  4. 填充因子不會自動維持;隨資料異動逐漸填滿。需定期 ALTER INDEX ... REBUILD WITH (FILLFACTOR = n) 重置。

經典比喻:學生編號

  • 100% (1,2,3,4,5...):插入第 5.5 號需將 5 之後全部後移 → 大量移動。
  • 50% (1,3,5,7,9...):插入第 5.5 號直接用編號 6 → 零移動。

權衡:填充因子越小 → 索引體積越大 (佔用更多記憶體/磁碟) → 但寫入效能越穩定。

適用場景與設定建議

場景建議 Fill Factor理由
唯讀/極少寫入 (資料倉儲、歷史表)100 (或 0)無分裂風險,極大化空間利用率
高頻插入、鍵值隨機 (GUID、Identity 非遞增)70-80預留空間吸收隨機插入,減少分裂
高頻更新導致鍵值長度變化 (VARCHAR 更新變長)70-80預留空間容納就地更新展開
遞增鍵 (Identity、日期) 且僅尾端插入100永遠在尾端追加,不會分裂既有頁

設定語法

-- 建立索引時指定
CREATE INDEX IX_Orders_CustDate ON Orders (CustomerID, OrderDate)
WITH (FILLFACTOR = 80);

-- 重建索引時重設
ALTER INDEX IX_Orders_CustDate ON Orders
REBUILD WITH (FILLFACTOR = 80);

常見誤區

  1. 以為設定後永久生效:實際上隨寫入逐漸失效,需納入維護計畫定期重建。
  2. 所有表統一設 80%:應依寫入模式、鍵值分佈、更新頻率個別評估。
  3. 忽略非叢集索引:非叢集索引葉頁同樣會分裂,同樣需要評估填充因子。

監控頁面分裂

-- 即時監控
SELECT * FROM sys.dm_db_index_operational_stats(DB_ID(), NULL, NULL, NULL)
WHERE leaf_allocation_count > 0;  -- 發生分裂的索引

-- 歷史累積
SELECT object_name(object_id) AS TableName, name AS IndexName,
       leaf_allocation_count AS PageSplits
FROM sys.dm_db_index_operational_stats(DB_ID(), NULL, NULL, NULL)
ORDER BY leaf_allocation_count DESC;

填充因子是「以空間換寫入穩定」的調優槓桿,善用之可大幅降低高寫入負載下的頁面分裂與碎片產生。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved