Если бы я решал эту проблему, я бы хотел найти следующие вещи:
- Если это практически возможно, убедитесь, что никто не монополизирует таблицу (т. Е. Блокирует ее)
- Убедитесь, что соединяемые столбцы проиндексированы (т. Е.
ms.user_B
, amc.user_B
) - Обновите столбцы в пакетах, используя
UPDATE TOP (100) ms SET ...
Элемент 3 на самом деле довольно хорошважно при выполнении больших вставок / обновлений / удалений.SQL Server создает журнал, чтобы отменить эту операцию, если она частично завершается сбоем, и это становится все более дорогостоящим.Если вам нужно обновить ряды шириной 1 м, это может быть намного быстрее для работы с 20 пакетами по 50 000 строк.Я видел совет, утверждающий, что это имеет огромное значение (и это делает AFAICT).Кроме того, это препятствует тому, чтобы запросы для таблицы увеличивались в очереди.
Но есть два предостережения: 1. Вы будете фиксировать каждый пакет отдельно, поэтому вы хотите убедиться, что ваша операция может выдержать «частично выполненный»,(Я предполагаю, что этот можно просто перезапустить.) 2. Вы должны быть в состоянии определить, какие столбцы обновляются.
Итак, в вашем случае, возможно:
declare @update_date datetime;
set @update_date = getdate();
while 1 = 1
begin
update top(10000) ms set
user_B_total_duration = amc.total_duration,
last_updated = @update_date
from
monthly_statistics ms
inner join aggregate_monthly_conversations amc
on ms.user_B = amc.user_B
where
ms.last_updated < @update_date;
if @@rowcount = 0 break;
end
Вы также можете добавить отпечаток, чтобы сказать, как далеко вы находитесь.