2009-01-28 158 views
10

我有一個數據庫,其中包含大量當前爲NTEXT的字段。SQL Server,將NTEXT轉換爲NVARCHAR(MAX)

升級到SQL 2005後,我們運行了一些將這些轉換爲NVARCHAR(MAX)的性能測試。

如果你讀這篇文章:

http://geekswithblogs.net/johnsPerfBlog/archive/2008/04/16/ntext-vs-nvarcharmax-in-sql-2005.aspx

這說明了一個簡單的ALTER COLUMN不會將數據重新組織成行。

我用我的數據體驗了這一點。如果我們只是運行ALTER COLUMN,我們實際上在某些地區的性能會差很多。但是,如果我爲所有這些字段運行UPDATE TABLE SET Column = Column,那麼我們將獲得極大的性能提升。

我遇到的問題是數據庫由成百上千個記錄的這些列組成。一個簡單的測試(在低性能虛擬機上)有一張表,其中包含一個包含700萬條記錄的單個NTEXT列,需要5個小時才能更新。

任何人都可以提供任何建議,如何以更有效的方式更新數據,最大限度地減少停機時間和鎖?

編輯:我的備份解決方案是更新塊中的數據隨着時間的推移,但是,與我們的數據,這導致更糟糕的表現,直到所有的記錄已更新,這個時間越短越好,所以我仍然尋找更快的方式來更新。

回答

6

如果你無法獲得計劃停機時間....

創建兩個新的欄目: 爲nvarchar(最大) processedflag INT DEFAULT 0

在processedflag創建一個非聚集索引

您有可用的UPDATE TOP(您想更新由主鍵排序的頂部)。

在更新過程中只需設置processedflag爲1,以便下一次更新將只更新的處理標誌仍是0

您可以使用@@ ROWCOUNT更新後,看看你是否可以退出循環。

我建議在每次更新查詢後使用WAITFOR幾秒鐘以使其他查詢有機會獲取表上的鎖定並且不會超載磁盤使用率。

3

如何批量運行更新 - 一次更新1000行。

您將使用一個while循環來增加一個計數器,對應於更新查詢的每次迭代中要更新的行的ID。這可能不會加快更新所有700萬條記錄所花費的時間,但它會使得用戶由於記錄鎖定而出現錯誤的可能性小得多。

+0

是的,這是我目前的計劃,需要很多組織才能完成所有工作,但應該可以實現。我也一次只更新一個字段,所以在我準備更新該列之前,我的性能不會下降。我只是希望有一些神奇的解決方案,我不知道。 – 2009-01-28 11:51:53

1

在低性能虛擬機上運行數據庫測試並不真正指示生產性能,涉及的繁重IO將需要快速磁盤陣列,虛擬化將對其進行限制。

3

如果你能獲得計劃停機時間:

  1. 備份數據庫
  2. 更改恢復模式,以簡單
  3. 從你正在更新
  4. 添加列maintenanceflag表(INT刪除所有索引DEFAULT 0)與非聚集索引
  5. 運行: UPDATE TOP 1000 表名 SET nvarchar from ntext , maintenanceflag = 1 WHERE maintenanceflag = 0

多個所需次數(一個循環中有延遲)。

完成後,執行另一次備份,然後將恢復模型更改回原來的狀態並添加舊索引。

請記住,該表上的每個索引或觸發器都會導致額外的磁盤I/O,並且簡單恢復模式會最小化日誌文件I/O。

0

您可能還會考慮測試以查看SSIS包是否可以更有效地完成此操作。

無論您做什麼,都可以將其設置爲可以在非工作時間安排和運行的自動化流程。您嘗試訪問數據的feweer用戶越快,一切就會越快。如果可能的話,挑出三到四個最關鍵的變化,並將數據庫記錄下來(在正常關閉的時間內),並以單用戶模式進行。一旦你得到最重要的,其他人可以安排一個或兩個晚上。

相關問題