更新十亿行 table
Updating billion rows table
我们有一个 table 有十亿行。我们只想将所有行的两列更新为 NULL。我们试图分批进行。但是,我们担心性能问题。我们在此 table 上有聚簇列存储索引。在这三列上创建复合非聚集索引会有帮助吗?或者我们可以将 table 重新加载到新的 table 并交换 tables 吗?
任何意见都会非常有帮助。
DECLARE @notNULLRecordsCount INT;
SET @notNULLRecordsCount = 1;
WHILE @notNULLRecordsCount > 0
BEGIN
BEGIN TRANSACTION;
UPDATE TOP (100000)
dbo.BillionRowsTable
SET Column1 = NULL,
Column2 = NULL,
Column3 = NULL
WHERE Column1 IS NOT NULL OR Column2 IS NOT NULL OR Column3 IS NOT NULL;
SET @notNULLRecordsCount = @@ROWCOUNT;
COMMIT TRANSACTION;
END
我的经验是索引实际上会减慢速度,因为必须维护索引。
保持交易开放是不好的。将所有这些包装在一个事务中并不好。如果您打算将它们全部包装在一个事务中,那么就没有必要将它们分解。
如果您可以只在一列上键入(没有 or
),它会更快。
你可以缩短这个
select 1;
WHILE @@ROWCOUNT > 0
BEGIN
UPDATE TOP (100000)
dbo.BillionRowsTable
SET Column1 = NULL,
Column2 = NULL,
Column3 = NULL
WHERE Column1 IS NOT NULL
OR Column2 IS NOT NULL
OR Column3 IS NOT NULL
END
去掉 or
select 1;
WHILE @@ROWCOUNT > 0
BEGIN
UPDATE TOP (100000)
dbo.BillionRowsTable
SET Column1 = NULL,
Column2 = NULL,
Column3 = NULL
WHERE Column1 IS NOT NULL
END
select 1;
WHILE @@ROWCOUNT > 0
BEGIN
UPDATE TOP (100000)
dbo.BillionRowsTable
SET Column2 = NULL,
Column3 = NULL
WHERE Column2 IS NOT NULL
END
select 1;
WHILE @@ROWCOUNT > 0
BEGIN
UPDATE TOP (100000)
dbo.BillionRowsTable
SET Column3 = NULL
WHERE Column3 IS NOT NULL
END
感谢@Paparazzo 的建议,我们决定使用单列将其作为两阶段更新来执行。我们一次将 Column1 用作 NULL,另一次将 Column1 用作 NOT NULL,这样我们就覆盖了所有行。
select 1;
WHILE @@ROWCOUNT > 0
BEGIN
BEGIN TRANSACTION;
UPDATE TOP (100000)
dbo.BillionRowsTable
SET Column2 = NULL,
Column3 = NULL
WHERE Column1 IS NULL;
COMMIT TRANSACTION;
END
select 1;
WHILE @@ROWCOUNT > 0
BEGIN
BEGIN TRANSACTION;
UPDATE TOP (100000)
dbo.BillionRowsTable
SET Column1= NULL,
Column2 = NULL,
Column3 = NULL
WHERE Column1 IS NOT NULL;
COMMIT TRANSACTION;
END
我们有一个 table 有十亿行。我们只想将所有行的两列更新为 NULL。我们试图分批进行。但是,我们担心性能问题。我们在此 table 上有聚簇列存储索引。在这三列上创建复合非聚集索引会有帮助吗?或者我们可以将 table 重新加载到新的 table 并交换 tables 吗?
任何意见都会非常有帮助。
DECLARE @notNULLRecordsCount INT;
SET @notNULLRecordsCount = 1;
WHILE @notNULLRecordsCount > 0
BEGIN
BEGIN TRANSACTION;
UPDATE TOP (100000)
dbo.BillionRowsTable
SET Column1 = NULL,
Column2 = NULL,
Column3 = NULL
WHERE Column1 IS NOT NULL OR Column2 IS NOT NULL OR Column3 IS NOT NULL;
SET @notNULLRecordsCount = @@ROWCOUNT;
COMMIT TRANSACTION;
END
我的经验是索引实际上会减慢速度,因为必须维护索引。
保持交易开放是不好的。将所有这些包装在一个事务中并不好。如果您打算将它们全部包装在一个事务中,那么就没有必要将它们分解。
如果您可以只在一列上键入(没有 or
),它会更快。
你可以缩短这个
select 1;
WHILE @@ROWCOUNT > 0
BEGIN
UPDATE TOP (100000)
dbo.BillionRowsTable
SET Column1 = NULL,
Column2 = NULL,
Column3 = NULL
WHERE Column1 IS NOT NULL
OR Column2 IS NOT NULL
OR Column3 IS NOT NULL
END
去掉 or
select 1;
WHILE @@ROWCOUNT > 0
BEGIN
UPDATE TOP (100000)
dbo.BillionRowsTable
SET Column1 = NULL,
Column2 = NULL,
Column3 = NULL
WHERE Column1 IS NOT NULL
END
select 1;
WHILE @@ROWCOUNT > 0
BEGIN
UPDATE TOP (100000)
dbo.BillionRowsTable
SET Column2 = NULL,
Column3 = NULL
WHERE Column2 IS NOT NULL
END
select 1;
WHILE @@ROWCOUNT > 0
BEGIN
UPDATE TOP (100000)
dbo.BillionRowsTable
SET Column3 = NULL
WHERE Column3 IS NOT NULL
END
感谢@Paparazzo 的建议,我们决定使用单列将其作为两阶段更新来执行。我们一次将 Column1 用作 NULL,另一次将 Column1 用作 NOT NULL,这样我们就覆盖了所有行。
select 1;
WHILE @@ROWCOUNT > 0
BEGIN
BEGIN TRANSACTION;
UPDATE TOP (100000)
dbo.BillionRowsTable
SET Column2 = NULL,
Column3 = NULL
WHERE Column1 IS NULL;
COMMIT TRANSACTION;
END
select 1;
WHILE @@ROWCOUNT > 0
BEGIN
BEGIN TRANSACTION;
UPDATE TOP (100000)
dbo.BillionRowsTable
SET Column1= NULL,
Column2 = NULL,
Column3 = NULL
WHERE Column1 IS NOT NULL;
COMMIT TRANSACTION;
END