Sql-Server

如何對大表進行 DDL 更改並導致最小的伺服器和對象爭用?

  • January 17, 2020

我在我最近繼承的數據庫中處理了很多大表(每個表都有數十億到數百億條記錄)。我看到了一些明確的 DDL 更改,這些更改將使數據庫的案例受益,但我很難實現它們,因為數據庫可以承受非常小的爭用。(基本上,如果一個繁重的查詢執行超過一兩分鐘,它就必須被殺死。)

即使在維護視窗期間,這些更改也會太長並且會超過我分配的時間(最多 1 小時,因為實際上沒有任何休息時間)。

我想要進行的更改類型是創建索引、添加持久計算列、創建索引視圖和正常索引調整。如果有一種方法可以迭代地執行任何這些操作並在迭代之間暫停,那麼我可以避免花費一段時間的總時間,因為至少我可以允許其他程序在兩者之間執行,而不是積壓。

我能想到的唯一想法是,如果我在可以進行 DDL 更改的單獨伺服器上維護數據庫的副本,然後將我的應用程序重新指向該伺服器。然後使用 DDL 更改更新第一台伺服器,使其同步,然後下次我需要進行更新時,我可以重複該過程。

編輯:我在 SQL Server 2016 企業版上。

我發現有助於創建大索引的最佳方法是 (1) 有足夠的 RAM,(2) 在索引創建開始之前有一個緩慢的時間,以及 (3)SELECT...INTO將索引欄位中的一個執行到一個臨時表中ORDER BY在創建索引之前的所需索引順序。在某些情況下,這可以將處理速度提高 75%(我迄今尚未完全確定)。

此外,如果您可以添加其他未使用的高性能驅動器或驅動器陣列(首選 SSD)並在該驅動器陣列上的文件組上創建索引,這可以大大提高索引創建性能。

要修改現有索引,請使用上述提示創建新索引,然後在檢查新索引上的索引使用情況一段時間後 DROP 現有索引。(為什麼?我以應該提高性能的方式修改了一些索引,卻發現整體性能下降。當我創建新索引時,我可以監視 SQL Server 是否要使用它,和/或通過強制指數。)

當然,既然您有 SQL Server 2016 EE,請使用 ONLINE=ON 選項。這可以最大限度地減少創建索引時的鎖定,並且最適合非聚集索引的創建或更改。聚集索引會重新組織整個表,所以無論發生什麼都需要一些時間。

我能想到的唯一想法是,如果我在可以進行 DDL 更改的單獨伺服器上維護數據庫的副本,然後將我的應用程序重新指向該伺服器。

相反,考慮只建構一個新表,並從現有表中增量載入它(更改跟踪甚至觸發器之類的東西在這裡可以提供幫助)。然後在您的短視窗期間,執行最終同步,並重命名表。

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