核心結論
對堆疊建立叢集索引後再刪除,以此整理碎片,是極度不建議的做法(僅次於收縮資料庫)。這會導致所有非叢集索引被重建兩次,造成嚴重效能衝擊與記錄膨脹。
為何這麼差?
非叢集索引的每一列都包含指向基底資料的指標:
- 若基底為堆疊,指標為 RID(檔案:頁:槽位)。
- 若基底為叢集索引,指標為叢集索引鍵值。
當您建立叢集索引時,所有非叢集索引必須從 RID 重建為叢集鍵;當您刪除該叢集索引時,又必須從叢集鍵重建回 RID。這就是「重建兩次」的由來。
SQL Server 2008 的 ALTER TABLE ... REBUILD 也不好
雖然 SQL Server 2008 引入 ALTER TABLE ... REBUILD 可整理堆疊碎片,但這會改變所有資料列的 RID,同樣導致所有非叢集索引重建一次,同樣邪惡。
正確做法
- 建立叢集索引並保留: 選擇理想的叢集鍵(窄、唯一、極少變動、遞增)。參考 Kimberly Tripp 的文章〈Ever-increasing clustering key〉。
- 若必須保持堆疊: 接受碎片存在,或透過匯出/匯入資料重建資料表(停機維護窗口)。
相關資源
- 〈What Happens if I Drop a Clustered Index?〉:說明非叢集索引指標變化。
- 〈Indexes From Every Angle: What happens to non-clustered indexes when the table structure is changed?〉:列出會導致非叢集索引重建的操作清單。