Обновление таблицы миллиардов строк

У нас есть таблица с миллиардом строк. Мы просто хотим обновить два столбца до NULL для всех строк. Мы пытались сделать это партиями. Но мы обеспокоены проблемами с производительностью. У нас есть кластеризованный индекс columnstore для этой таблицы. Поможет ли создание составного некластеризованного индекса для этих трех столбцов? или мы можем перезагрузить таблицу в новую таблицу и поменять местами таблицы?

Любые материалы будут очень полезны.

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 ответа

Решение

Мой опыт показывает, что индексы на самом деле замедляют это, поскольку индексы должны поддерживаться.

Оставлять открытую транзакцию нехорошо. Оборачивать все это в транзакцию нехорошо. Если вы собираетесь обернуть их все в транзакции, то нет смысла разбивать их.

Если бы вы могли ввести только один столбец (нет 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
Другие вопросы по тегам