更新十亿行表

时间:2018-04-10 12:58:24

标签: sql-server database-performance bulkupdate

我们有一个十亿行的表。我们只想为所有行将两列更新为NULL。我们试图分批进行此操作。但是,我们担心性能问题。我们在此表上有聚簇列存储索引。在这三列上创建复合非聚集索引会有帮助吗?或者我们可以将表重新加载到新表和&交换表?

任何输入都会非常有用。

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 

2 个答案:

答案 0 :(得分:3)

我的经验是,索引实际上会降低速度,因为必须维护索引。

让交易保持开放并不好。在交易中包装所有这些并不好。如果你打算将它们全部包装在一个交易中,那就没有意图将它们分解。

如果你只能键入一列(没有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

答案 1 :(得分:0)

感谢@Paparazzo的建议,我们决定使用单列作为两阶段UPDATE进行此操作。我们一次使用Column1作为NULL,另一个使用Column1作为NOT NULL,以便我们覆盖所有行。

 $config = Array(
          'protocol' => 'smtp',
          'smtp_host' => 'ssl://smtp.zoho.com',
          'smtp_port' => 465,
          'smtp_user' => 'malinga@bckonnect.com',
          'smtp_pass' => 'mal@pass',
          'mailtype' => 'html'
    );