Почему этот блок запроса вставляется? - PullRequest
3 голосов
/ 24 ноября 2011

Существует процесс, который выполняется каждый час, который нужно вставить в таблицу1, но когда выполняется приведенный ниже запрос, вставки блокируются.Кто-нибудь может объяснить почему?Я понимаю, что подсказки блокировки - это просто подсказки, и SQL может предпочесть их игнорировать.Таблица1 имеет 300 метров строк, и мне нужно обновить значения в ColumnA.Я делаю это по частям, чтобы помочь с откатом в случае, если процесс должен быть остановлен, следовательно, цикл while.

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
go

declare @start bigint
declare @end bigint
declare @max bigint
declare @step int

set @step = 50000
set @start = 17953095
set @end = @start + @step
set @max = @start + 2000000

while ( @end < @max )
begin

waitfor delay '00:00:10'

begin transaction

update [table1] with (ROWLOCK)
set [table1].[ColumnA] = [table2].[ColumnA]
from [table2] (nolock)
where [table2].[ColumnB] = [table1].[ColumnB] 
and [table1].ID >= @start 
and [table1].ID <  @end

commit transaction

print @end

if @end >= @max 
begin
    break
end

set @start = @end
set @end = @end + @step

end

print @end

Можно ли сделать это по-другому, чтобы он не блокировал вставки илидругие обновления?Больше ничего не нужно будет работать с ColumnA, кроме моего запроса выше.

1 Ответ

2 голосов
/ 24 ноября 2011

Вы можете попробовать использовать меньший размер партии. SQL Server увеличивает блокировку строк прямо до блокировок таблиц при превышении определенного порогового значения для MSDN :

Компонент Database Engine не увеличивает блокировку строк или диапазонов ключей на странице блокирует, но увеличивает их непосредственно до блокировок таблицы.
...
...
Повышение блокировки запускается, когда повышение блокировки не отключено таблицу с помощью опции ALTER TABLE SET LOCK_ESCALATION, и когда выполняется одно из следующих условий:

Один оператор Transact-SQL получает как минимум 5000 блокировок на одиночная таблица без разделов или индекс.

Один оператор Transact-SQL получает как минимум 5000 блокировок на один раздел многораздельной таблицы и ALTER TABLE SET Для параметра LOCK_ESCALATION установлено значение AUTO.

Количество блокировок в экземпляре компонента Database Engine превышает пороги памяти или конфигурации.

Если блокировки не могут быть расширены из-за конфликтов блокировки, База данных Двигатель периодически вызывает повышение блокировки при каждых 1250 новых блокировках Приобретенная.

Ваш текущий размер партии 50 000 значительно превышает этот порог.

Еще одна вещь, о которой стоит подумать, - есть ли у вас подходящие индексы для соответствия вашему предложению WHERE - убедитесь, что он максимально оптимальный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...