在 SQL Server 上重建碎片索引
我們有一個 SQL Server 數據庫來支持我們的 SAAS Web 應用程序。它是一個 SQL Azure 數據庫,託管在 S3 標準計劃上(100 個 DTU 單位 - 足以滿足我們的需要)。
我們的數據庫索引碎片非常快,以至於在 3-4 天后,我們很多使用較多的表通常碎片超過 40%。如果離開,2 週後會有大約 90% 的碎片化。在我們最常用的表中,我們有大約 200 萬行。
因此,為了對此進行排序,我們有一個每 3 天執行一次的腳本,它會查找 >20% 碎片的索引,然後我們重新建構這些索引(開啟線上)。
問題在於,當它執行時,應用程序在執行時變得非常緩慢且無響應約 2 小時。
是否有更好的策略來處理這種索引碎片,或者我可以研究其他任何方法來嘗試降低碎片的頻率?
謝謝。
如果索引由於大量活動影響任意使用者提供的值而快速碎片化,那麼它們可能無能為力。
如果嚴重碎片化的索引在
UNIQUEIDENTIFIER
列上,那麼當它們看到大量活動時,這些索引會迅速碎片化,因為數據實際上是隨機的。如果是這種情況,那麼您可以通過使用NEWSEQUENTIALID()
instead of 來大大減少這種情況NEWID()
,或者如果您在此處而不是在數據庫中生成 UUID,則可以在應用程序中使用等效項。如果您在 SQL Server 之外生成 UUID,請確保它們是按照 SQL Server 的排序順序按順序生成的(不同的生成器使用不同的字節順序),否則您將失去部分或全部好處。有關 .Net不生成與 SQL Server 具有相同排序屬性的 UUID以及如何使結果正常工作的參考,請參閱此內容。
UuidCreateSequential``NEWSEQUENTIALID()
還有什麼我可以研究以嘗試減少碎片的頻率嗎?
也許你可以找到一個適合
FillFactor
你的桌子。我建議你閱讀這篇關於它的文章:SQL Q & A Database Consistency, Temporary Tables, and More by Paul S. Randal
問:我們正在實施一項夜間數據庫維護計劃,其中包括提高索引性能。我聽說為索引設置“填充因子”選項可以完全消除維護索引的需要。這是真的?似乎我們數據庫中的某些索引存在碎片,而有些則沒有。我們是否應該為數據庫設置一個適用於所有索引的預設填充因子,如果是,我們應該使用什麼值?
A:填充因子設置確實可以用來部分緩解索引維護的需要,但很少能用它來完全消除這種需要。簡而言之,填充因子設置指示儲存引擎在創建或重建聚集索引和非聚集索引的頁面中保留一定百分比的可用空間。(請注意,在正常插入/更新/刪除操作期間不會保持填充因子設置。)例如,填充因子為 90 會留下 10% 的可用空間。填充因子 0 或 100 都沒有留下可用空間(這是造成很多混亂的根源)。這個想法是在頁面中留下空間,這允許頁面上的記錄擴展或在頁面上插入新記錄,而不會導致稱為頁面拆分的昂貴的、導致碎片的操作。您指定可用空間的百分比,以便頁面可以更加穩定地充滿,直到發生下一次索引維護操作,這會再次重置填充因子。訣竅是選擇一個百分比來最小化索引維護操作之間的頁面拆分。對於 OLTP(線上事務處理)數據庫,除了根據反複試驗為每個索引選擇填充因子外,沒有簡單的答案。對於索引不變的數據倉庫,填充因子應為 100%(意味著頁面上沒有剩餘空間)。數據庫的預設填充因子從預設的 100% 更改是非常罕見的,因為各種索引的最佳填充因子通常是不同的。SQL Server 2008 聯機叢書主題“填充因子”對此提供了更多資訊。另一種選擇是更改索引,以便不會發生頁面拆分。這可能涉及更改索引鍵以使插入不是隨機的(例如,通過不使用隨機 GUID 主鍵)或禁止更改可變長度列大小的操作。