Sql-Server

重建索引時除了“刪除和重新創建索引”之外會發生什麼,而重組命令中不會發生這種情況?

  • April 6, 2022

當觸發索引重組命令時,它不會刪除並重新創建索引。然而,就像重建一樣,它將對數據進行碎片整理並確保頁面的物理順序與鍵的邏輯順序一致。

那麼,除了delete and re-creation of the index在 r​​eorganize 命令中沒有發生的重建索引時會發生什麼?

例如:頁面在重建時遵循填充因子,從而釋放每個頁面中的空間。還有什麼?

在這裡您可以找到兩種活動之間的差異。

需要空間

無論舊索引中存在多少碎片,重建索引都需要在刪除舊索引之前建構新索引。這意味著您需要有足夠的可用空間來容納新索引。

重新組織索引首先將索引行壓縮在一起以嘗試釋放一些索引頁面,然後將剩餘頁面打亂以使其物理(分配)順序與邏輯(鍵)順序相同。這只需要一個 8 KB 的頁面,作為移動頁面的臨時儲存空間。因此,索引重組非常節省空間,這也是我為 SQL Server 2000 編寫原始 DBCC INDEXDEFRAG(ALTER INDEX … REORGANIZE 的前身)的原因之一。

如果您有空間限制,並且無法使用單分區重建,那麼重組是要走的路。

算法速度

索引重建將始終建構一個新索引,即使沒有碎片。重建所需的時間長度與索引的大小有關,而不是與其中的碎片量有關。

重組索引只處理存在的碎片,碎片越多,重組所需的時間就越長。

這意味著對於碎片較少的索引(例如,小於 30% 的碎片),重組索引通常更快,但對於碎片較多的索引,重建索引通常更快。這就是為什麼您可能已經看到 0 到 5-10% 的門檻值什麼都不做,5-10% 到 30% 的重組,30%+ 的重建。我在 Microsoft 時創建了此指南 - 請參閱此處。

生成的事務日誌

在 FULL 恢復模式下,索引重建是完全記錄的,因此事務日誌必須在單個事務中容納索引的完整大小。這也意味著可能需要對整個生成的事務日誌進行鏡像、發送到您的 AG 副本、通過複製進行掃描、備份等等。

在 SIMPLE 和 BULK_LOGGED 恢復模式中,由離線索引重建生成的事務日誌量將是最小的(線上索引重建總是完全記錄)——只是頁面和範圍的分配。但是,下一次執行的日誌備份(無論是在 BULK_LOGGED 中還是在切換到 FULL 之後)也將包含重建更改的所有擴展區,因此日誌備份的大小與重建在 FULL 恢復模式下完成的大小大致相同. 好處是及時,事務日誌本身不必在單個事務中重建期間容納索引的完整大小。

在所有恢復模式中,重新組織索引都是完全記錄的,但作為一系列小事務執行,因此不應導致事務日誌過度增長。當然,事務日誌只為執行的操作生成,對於重組來說可能更少,因為它只處理存在的碎片。

需要鎖

任何索引的離線索引重建都持有模式修改(即超級獨占)表鎖——不更新或讀取整個表。

任何索引的線上索引重建在操作開始時獲取一個短期共享表鎖,在整個操作過程中持有一個意圖共享表鎖(它只會阻塞排他和模式修改表鎖),然後獲取一個操作結束時的短期模式修改表鎖。“線上”有點用詞不當。從 SQL Server 2014 開始,您可以使用 WAIT_AT_LOW_PRIORITY 選項來延遲阻塞的可能性 - 請參閱此部落格文章。

索引重組在整個操作過程中都持有一個意圖排他表鎖,它只會阻止共享、排他和模式修改表鎖。我為 SQL Server 2000 編寫 DBCC INDEXDEFRAG 的主要原因之一是作為 DBCC DBREINDEX 的線上替代品。

可中斷與否

如果不回滾迄今為止所做的一切——它是原子的——全有或全無,就無法中斷索引重建操作。但是,在 SQL Server 2017 中,有一個可恢復的線上索引重建功能。

索引重組可能會被中斷,最壞的情況是單頁移動操作被回滾。

進度報告與否

索引重建沒有正確的進度報告。您可以通過查看 Progress Report: Online Index Profiler 事件中的 bigintdata1 列來破解它以進行線上索引操作,該列恰好顯示已掃描了多少行舊索引。您還可以通過查看 SPID 在 sys.dm_exec_requests 中完成的頁面讀取次數來破解它以進行索引操作。

索引重組操作填充 sys.dm_exec_requests 的 percent_complete 列,因此您可以輕鬆地衡量剩餘的工作量。事實上,DBCC INDEXDEFRAG 也用於進行進度報告,但不那麼優雅,它每 30 秒列印一個進度消息到您的連接。

統計數據

索引重建將始終使用相當於完整掃描(或採樣,對於索引分區或如果索引已分區)來重建索引列統計資訊。

索引重組看不到索引的總視圖,因此無法更新統計資訊,這意味著需要手動維護索引統計資訊。

概括

正如您所看到的,重建和重組之間有很多主要區別,但是對於您應該使用哪一個沒有正確的答案——那是您的選擇。

如果您的索引維護常式總是重新建構並且從不考慮重新組織,您應該重新考慮。通常最好重組一個碎片較少的索引並重建一個碎片較多的索引——以節省時間和資源。您會發現大多數索引維護產品和免費提供的腳本都允許您做出選擇。

和往常一樣,我推薦 Ola Hallengren 的免費程式碼,而不是編寫自己的索引維護解決方案(是的,其他人也做過類似的,但我認為 Ola 是迄今為止最好的和最廣泛使用的)。

來源連結

重建允許您指定填充因子。Reorg 將重新應用您在 sys.indexes 中看到的值(您在創建索引時指定的值)。

Rebuild 將根據全部數據為您提供新的統計數據。Reorg 不會給你新的統計數據。

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