2012-04-16 95 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

相关问题