Fill Factor (填充因子):指定索引葉層頁面資料充滿度百分比 (0-100)。僅在建立/重建索引時生效,預留空間減少未來插入導致的頁面分裂。
0 或 100:頁面完全填滿 (預設)。60:頁面僅填 60%,保留 40% 空間供後續插入/更新展開。
INSERT/UPDATE 導致鍵值需插入頁面中間時,若有預留空間 → 就地插入,無頁面分裂。ALTER INDEX ... REBUILD WITH (FILLFACTOR = n) 重置。權衡:填充因子越小 → 索引體積越大 (佔用更多記憶體/磁碟) → 但寫入效能越穩定。
| 場景 | 建議 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);
-- 即時監控
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;
填充因子是「以空間換寫入穩定」的調優槓桿,善用之可大幅降低高寫入負載下的頁面分裂與碎片產生。