对于包含数十亿行的表,将数据类型从int更改为bigint

时间:2012-04-16 20:55:25

标签: sql-server type-conversion

我有几百万个表,在一些表中有数十亿行,有一列作为int现在我正在改为bigint。我尝试使用SSMS更改数据类型,并在事务日志已满几小时后失败。

我采用的另一种方法是创建一个新列并开始批量更新旧列到新列的值,方法是将ROWCOUNT属性设置为100000,它可以工作,但速度非常慢,并且它声明了完整的服务器内存。使用这种方法,可能需要几天时间才能完成,而且在生产中是不可接受的。

更改数据类型的快速\最佳方法是什么?源列不是标识列和重复列,并且允许为null。该表有其他列的索引,禁用索引会加快进程吗?是否会添加Begin Tran和Commit帮助?

2 个答案:

答案 0 :(得分:7)

我对ALTER COLUMN进行了测试,显示了进行更改所需的实际时间。结果表明,ALTER COLUMN 瞬间,所需时间呈线性增长。

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

我的建议是按照你的建议批量处理。创建一个新列,并使用 ROWCOUNT WAITFOR 的组合预先填充列。

对脚本进行编码,以便从表中读取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;

答案 1 :(得分:0)

一个简单的alter table <table> alter column <column> bigint null应该基本上没时间。没有任何转换问题或空检查 - 我不明白为什么这不会是相对即时的

如果你通过GUI完成它,它可能会尝试创建临时表,删除现有表,并创建一个新表 - 绝对不要那样做