Оптимизатор, скорее всего, решит заблокировать всю таблицу, так как это проще сделать, если ему нужно удалить столько строк. В таком случае я удаляю кусками.
while(1 = 1)
begin
with cte
as
(
select *
from Table1
where Id not in (select Id from Table2)
)
delete top(1000) cte
if @@rowcount = 0
break
waitfor delay '00:00:01' -- give it some rest :)
end
Таким образом, запрос удаляет 1000 строк за раз. Оптимизатор, скорее всего, заблокирует только страницу для удаления строк, а не всю таблицу.
Общее время выполнения этого запроса будет больше, но оно не будет блокировать других абонентов.
Отказ от ответственности: предполагается MS SQL.
Другой подход заключается в использовании SNAPSHOT
транзакции. Таким образом, средства чтения таблиц не будут блокироваться во время удаления строк.