Sql-Server-2005

通過創建聚集索引並立即刪除它來對 HEAP 進行碎片整理

  • December 24, 2021

我正在編寫一個腳本,該腳本旨在通過創建一個帶有聚集索引的虛擬 col 然後立即刪除它來對基於 HEAP 的表進行碎片整理。(這是別人的應用程序,我不想做任何永久性的改變——不過他們做得很好。)

ALTER TABLE my_heap ADD dummy BIGINT IDENTITY;
GO
CREATE CLUSTERED INDEX ix_dummy ON my_heap (dummy);
GO
-- need to wait here until index completes
DROP INDEX ix_dummy ON my_heap;
ALTER TABLE my_heap DROP COLUMN dummy;
GO

當我執行腳本的各個步驟時,它工作正常。當我一次執行它時,似乎什麼都沒有發生(碎片水平不會下降)。我相信這是因為 DROP 發生在 CREATE CLUSTERED 完成之前 - 所以 CREATE CLUSTERED 沒有時間做它的事情。

如何讓 DROP 等待 CREATE CLUSTERED 完成?我正在為大約 30 張桌子這樣做,所以我不想為每張桌子設置一個簡單的 WAITFOR DELAY 15 分鐘。

PS 使用 SQL Server 2005

如何讓 DROP 等待 CREATE CLUSTERED 完成?

你沒有,它已經做到了。語句是順序的,即同步的,一個接一個。

什麼是堆儲存? 保羅蘭德爾解釋說

所以你真正擁有的只是一堆扔在桌子上的紙,幾乎是字面上的。您的操作在右下角整齊地編號頁面,按順序整理頁面,綁定它們,然後……解開並再次將它們扔回桌子上。總成就接近於零。當然,您將通過整理和刪除轉發頁面重新獲得一些使用,數據頁面可能會更緊湊一點。除此之外,它就像你開始時一樣混亂。

堆沒有像預期的那樣收縮的部分原因是虛擬列的每行有 8 個字節。這可能很大,具體取決於典型行的平均大小。然後你刪除 column dummy,使該空間未使用。在不添加和刪除的情況下嘗試此操作,dummy並在其他列上創建聚集索引。它們不必是唯一的。

引用自:https://dba.stackexchange.com/questions/28955