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

use*_*121 4 sql-server type-conversion

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

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

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

Rob*_*son 7

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

RecordCt    Elapsed Mcs
----------- -----------
      10000      184019
     100000     1814181
    1000000    18410841
Run Code Online (Sandbox Code Playgroud)

我的建议是按照你的建议批量处理它.创建一个新列,并使用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;
Run Code Online (Sandbox Code Playgroud)