Блокирует ли SQL Server таблицы, когда запросы возвращают результаты, превышающие 5000 записей?
Обычно нет.
* задокументировано , что 5000 - это магическое число для механизма базы данных, который сначала пытается увеличить блокировку (с последующими дальнейшими попытками с 1250 приращениями), но если только он не работает с повторяющимся уровнем чтения или сериализуемым уровнем изоляции, этокак правило, не ударится, просто вернув 5,0000 предметов за SELECT
.Уровень фиксации чтения по умолчанию снимет блокировки, как только данные будут прочитаны, поэтому никогда не достигните порогового значения.
Влияние уровня изоляции можно увидеть в следующем примере.
CREATE TABLE T(C INT PRIMARY KEY);
INSERT INTO T
SELECT TOP 10000 ROW_NUMBER() OVER (ORDER BY @@SPID)
FROM sys.all_objects o1, sys.all_objects o2
И (использует недокументированные флаги трассировки, поэтому следует использовать только в среде разработки)
DBCC TRACEON(3604,611);
/*5,000 key locks are held*/
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN TRAN
SELECT COUNT(*) FROM (SELECT TOP 5000 C FROM T) T
SELECT resource_type, request_mode, count(*) FROM sys.dm_tran_locks where request_session_id = @@spid GROUP BY resource_type, request_mode;
COMMIT
/*No key locks are held. They have been escalated to an object level lock. The messages tab shows the lock escalation (in my case after 6248 locks not 5,000)*/
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN TRAN
SELECT COUNT(*) FROM (SELECT TOP 10000 C FROM T) T
SELECT resource_type, request_mode, count(*) FROM sys.dm_tran_locks where request_session_id = @@spid GROUP BY resource_type, request_mode;
COMMIT
/*No key locks are held. They are released straight away at this isolation level. The messages tab shows no lock escalation messages*/
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN TRAN
SELECT COUNT(*) FROM (SELECT TOP 10000 C FROM T) T
SELECT * FROM sys.dm_tran_locks where request_session_id = @@spid
COMMIT
DBCC TRACEOFF(3604,611);