Расширение блокировки вряд ли вообще связано с SELECT
частью вашего заявления.
Это естественное следствие вставки большого количества строк.
Расширение блокировки запускается, если расширение блокировки не отключено для таблицы с помощью параметра ALTER TABLE SET LOCK_ESCALATION и при наличии одного из следующих условий:
- Одна инструкция Transact-SQL устанавливает не менее 5000 блокировок на одну неразделенную таблицу или индекс.
- Одна инструкция Transact-SQL устанавливает не менее 5000 блокировок на один раздел многораздельной таблицы, а для параметра ALTER TABLE SET LOCK_ESCALATION установлено значение AUTO.
- Количество блокировок в экземпляре компонента Database Engine превышает пороговые значения памяти или конфигурации.
Если укрупнение блокировок невозможно из-за конфликтов блокировок, Компонент Database Engine периодически инициирует укрупнение блокировок после получения каждых 1250 новых блокировок.
Вы можете легко убедиться в этом сами, отследив событие эскалации блокировки в Profiler или просто попробовав приведенное ниже с различными размерами пакетов. Для меня TOP (6228)
показывает 6250 удерживаемых блокировок, но TOP (6229)
оно внезапно падает до 1, когда начинается укрупнение блокировок. Точные цифры могут отличаться (в зависимости от настроек базы данных и доступных ресурсов). Используйте метод проб и ошибок, чтобы найти порог, при котором для вас появляется эскалация блокировки.
CREATE TABLE [dbo].[Destination]
(
proj_details_sid INT,
period_sid INT,
sales INT,
units INT
)
BEGIN TRAN --So locks are held for us to count in the next statement
INSERT INTO [dbo].[Destination]
SELECT TOP (6229) 1,
1,
1,
1
FROM master..spt_values v1,
master..spt_values v2
SELECT COUNT(*)
FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID;
COMMIT
DROP TABLE [dbo].[Destination]
Вы вставляете 50 000 строк, поэтому почти наверняка будет предпринята попытка укрупнения блокировки.
Статья Как устранить проблемы с блокировкой, вызванные укрупнением блокировки в SQL Server. довольно старый, но многие предложения все еще в силе.
- Разбейте большие пакетные операции на несколько более мелких операций (т. е. используйте меньший размер пакета)
- Расширение блокировки не может произойти, если другой SPID в настоящее время удерживает несовместимую блокировку таблицы. Пример, который они приводят, - это выполнение другого сеанса.
BEGIN TRAN
SELECT * FROM mytable (UPDLOCK, HOLDLOCK) WHERE 1=0
WAITFOR DELAY '1:00:00'
COMMIT TRAN
- Отключите расширение блокировки, включив флаг трассировки 1211. Однако это глобальный параметр, который может вызвать серьезные проблемы. Существует более новая опция 1224, которая менее проблематична, но по-прежнему глобальна. .
Другим вариантом может быть ALTER TABLE blah SET (LOCK_ESCALATION = DISABLE)
, но это все еще не очень целенаправленно, поскольку влияет на все запросы к таблице, а не только на ваш единственный сценарий здесь.
Так что я бы выбрал вариант 1 или, возможно, вариант 2 и обесценил бы остальные.
person
Martin Smith
schedule
10.09.2016
Destination
, которыеnolock
не вступят в силу вexists clause
, не так ли? - person Prisoner   schedule 09.09.2016SELECT
. Блокировки, снятые вновь вставленными строками в пакете, скорее всего, вызовут любые проблемы с укрупнением блокировок, а не частьSELECT
. На уровне изоляции по умолчаниюSELECT
все равно снимет блокировку строки, как только она будет прочитана. - person Martin Smith   schedule 09.09.2016READUNCOMMITTED and NOLOCK cannot be specified for tables modified by insert, update, or delete operations
, поэтому он не будет применять таблицу вexists clause
? - person Prisoner   schedule 09.09.2016READUNCOMMITTED and NOLOCK cannot be specified for tables modified by insert, update, or delete operations. The SQL Server query optimizer ignores the READUNCOMMITTED and NOLOCK hints in the FROM clause that apply to the target table of an UPDATE or DELETE statement.
. Иexists clause
должен быть частьюfrom clause
? - person Prisoner   schedule 09.09.2016EXISTS
и использовать вместо негоWITH IGNORE_DUP_KEY
, верно? Я думаю, что это было бы более эффективным, а также. См. stackoverflow.com/a/2513187/78522. - person Patrick Honorez   schedule 09.09.2016