2015-08-04 3 views
3

У меня есть таблица с 2 миллиарда строк. Режим восстановления прост.Столбец UPDATE для большой таблицы с одним значением

У меня есть простая задача сделать:

UPDATE myTable SET columnA = 'X' 

Задача кажется простой на первый, но везде, где я читал, что это лучше сделать SELECT INTO другую таблицу или сделать обновление партии.

Является ли обновление пакета обязательным? Будет ли запрос выше взорвать журнал транзакций?

Если я создаю другую таблицу, я наверняка исчерпаю место.

Любая справка будет полезна.

EDIT: У меня нет первичного ключа. Кроме того, нет индексов, никаких ограничений, ничего.

Возможно, это поможет?

SET rowcount 10000 
Update myTable 
set columnA ='X' 
where columnA <> 'X' 

while @@rowcount>0 

BEGIN 
SET rowcount 10000 
Update myTable 
set columnA ='X' 
where columnA <> 'X' 

end 

SET rowcount 0 
+0

Не забудьте установить базу данных для простого восстановления при выполнении этого. Очевидно, вы сначала захотите создать резервную копию. –

ответ

0

Выполнить его в партиях

Declare @pk integer = 0 
declare @max integer 
select @max = Max(primKeyCol) from myTable 
While @pk < @Max Begin 
     Update myTable set columnA = 'X' 
     Where primKeyCol Between @pk and @pk + 999 
     Set @pk += 1000 
End 
+0

У меня нет первичного ключа. –

0

Я предлагаю вам использовать пакетное обновление, так как этот вид UPDATE в большой таблице может вызвать много замков. я нашел хороший пример партии here

+1

Не могли бы вы объяснить запрос? Для меня это похоже, что он будет обновлять первые 1000 строк постоянно. Спасибо. –

+0

В вашем случае вы можете добавить предложение WHERE к вашему UPDATE и получить записи, что columnA не является «X». Таким образом, он выполнит инструкцию для строк, которые до этого не обновлялись. –

+0

Хорошо, это заставило бы его работать. Хотя таблица не используется никаким другим ресурсом. Это сделает обновление пакета бессмысленным? –

0

Попробуйте обновить 50.000 строк в то время

DECLARE @chk INT = 1 
WHILE @chk > 0 
BEGIN 
    ;WITH CTE as 
    (
    SELECT TOP 50000 columnA 
    FROM myTable 
    -- the reason for this check is to check for NULLS in columnA 
    -- otherwise it could just be columnA <> 'X' 
    WHERE exists(SELECT columnA EXCEPT SELECT 'X') 
) 
    UPDATE CTE SET columnA = 'X' 
    SET @chk = @@rowcount 
    WAITFOR DELAY '00:00:30' -- 30 seconds, may need to change it 
END 

От майкрософт Link

Использование SET ROWCOUNT не будет влиять на DELETE, INSERT и UPDATE в будущей версии SQL Server. Избегайте использования SET ROWCOUNT с операциями DELETE, INSERT и UPDATE в новых разработках, и планируете изменять приложения, которые в настоящее время используют его. Для аналогичного поведения используйте синтаксис TOP. Для получения дополнительной информации см. TOP (Transact-SQL).

+1

Здравствуйте, Это рекурсивно? Это похоже на одноразовое обновление в 50000 строк. Спасибо. –

+0

@DragosDurlut теперь в петле, добавлена ​​задержка –

+1

Почему 'WAITFOR DELAY'? – xanatos

0

Это довольно дикий и non-sql путь, но вы можете использовать ETL инструменты (такие как SSIS), чтобы избежать входа в значительной степени.

Отказ от ответственности. Это может быть трудоёмкий шаг и может занимать файловое пространство на вашем сервере.

Имейте две задачи потока данных (DFT1, DFT2).

DFT1

enter image description here

Используя преобразование Производный столбец, передать значение "А", а не фактическое значение columnA.

Плоский файл теперь будет иметь требуемые данные. Следующий шаг - импортировать это на стол.

Вне DFT, обрезайте этот стол сейчас. TRUNCATE, как вы, вероятно, знаете, не работает. Таким образом, ваш журнал транзакций не будет затронут.

И, наконец,

DFT2

Импорт данных на TABLEA из плоского файла.

enter image description here

SSIS внутренне делает минимальное протоколирование, так что опять журнал не будет операции Устанавливаются беспокоить слишком много.

Кроме того, я просто видел, что вы добавили тег ssis в свой вопрос, поэтому этот ответ должен быть действительным.

Смежные вопросы