2012-04-16 56 views
3

我有幾百萬的表和幾百億行的表,其中一列爲int,現在我正在更改爲bigint。我嘗試使用SSMS更改數據類型,並在事務日誌滿了幾個小時後失敗。將數據類型從int更改爲包含數十億行的表的數據類型

我採取的另一種方法是創建一個新的列,並開始更新從舊列到新列的價值,通過設置ROWCOUNT屬性爲100000,它的工作原理,但它非常緩慢,它聲稱完整的服務器內存。採用這種方法,可能需要幾天才能完成,而且在生產中不可接受。

什麼是更改數據類型的最快方式?源列不是標識列並且是重複的,並且允許爲null。該表在其他列上有索引,禁用索引是否會加快進程?將添加Begin Tran和Commit的幫助?

+0

您是否需要將此作爲生產能力,定期執行?或者這是一次性的事情? – 2012-04-16 20:57:36

+0

這隻需要完成一次 – user1337121 2012-04-16 21:15:23

回答

0

一個簡單的alter table <table> alter column <column> bigint null應該基本上沒有時間。將不會有任何轉換問題或空檢查 - 我不明白爲什麼這不會是相對即時

如果你通過GUI做它,它可能會嘗試創建一個臨時表,刪除現有的表格,並創建一個新的 - 絕對不要這樣做

+1

這些行的大小會增加。因此,如果頁面充滿行,則必須分配新頁面。 – 2012-04-16 22:23:46

7

我運行了ALTER COLUMN的測試,顯示了進行更改所需的實際時間。結果顯示ALTER COLUMN是而非是瞬時的,所需時間線性增長。

RecordCt Elapsed Mcs 
----------- ----------- 
     10000  184019 
    100000  1814181 
    1000000 18410841 

我的建議是按照您的建議對其進行批處理。創建一個新列,並使用ROWCOUNTWAITFOR的組合隨着時間的推移預填充列。

對腳本進行編碼,以便從表中讀取WAITFOR值。這樣,您可以在生產服務器開始停止時即時修改WAITFOR值。您可以在非高峯時段縮短WAITFOR。 (您甚至可以使用DMV來自動設置WAITFOR值,但這當然更復雜。)

這是一個複雜的更新,需要進行規劃和大量的保姆工作。

羅布


這裏是ALTER COLUMN測試代碼。

USE tempdb; 
SET NOCOUNT ON; 
GO 
IF EXISTS (SELECT * FROM sys.tables WHERE [object_id] = OBJECT_ID('dbo.TestTable')) 
    DROP TABLE dbo.TestTable; 
GO 
CREATE TABLE dbo.TestTable (
    ColID int    IDENTITY, 
    ColTest int    NULL, 
    ColGuid uniqueidentifier DEFAULT NEWSEQUENTIALID() 
); 
GO 

INSERT INTO dbo.TestTable DEFAULT VALUES; 
GO 10000 

UPDATE dbo.TestTable SET ColTest = ColID; 
GO 

DECLARE @t1 time(7) = SYSDATETIME(); 
DECLARE @t2 time(7); 

ALTER TABLE dbo.TestTable ALTER COLUMN ColTest bigint NULL; 

SET @t2 = SYSDATETIME(); 

SELECT 
    MAX(ColID)    AS RecordCt, 
    DATEDIFF(mcs, @t1, @t2) AS [Elapsed Mcs] 
FROM dbo.TestTable; 
+0

+1是一個非常完整的例子。我很好奇如果在表上有一個聚簇索引會發生什麼情況,並且在更改列之前,索引是用'FILLFACTOR = 80'重建的(行數將從24個字節增加到28個,增加了15個%)。它應該保存SQL Server分配新頁面。重複使用新的'BIGINT'列作爲關鍵字或覆蓋列的其他索引。 – 2012-04-17 02:00:45

+0

10k行結果如下:430,725 mcs;聚集索引:155,295 mcs;在'FILLFACTOR = 80'重建聚簇索引:98,647 mcs – 2012-04-17 02:13:42

+0

好問題,並感謝您發佈結果。 – 2012-04-17 15:21:51