Блокирует ли SQL таблицы, когда запросы возвращают результаты, превышающие 5000 записей?

#sql-server #sharepoint

#sql-server #sharepoint

Вопрос:

Я работаю в SharePoint и пытаюсь понять, почему существует ограничение в 5000 записей для представлений в списках, которые могут иметь гораздо большее число.

Мой вопрос касается не SharePoint, а SQL. Имеет ли SQL ограничение, описанное ниже, или это было что-то наложенное на SQL командой SharePoint?

По соображениям производительности всякий раз, когда SQL Server выполняет один запрос, который возвращает более 5000 элементов, в таблице SQL происходит эскалация блокировок. В результате вся таблица будет заблокирована. Поскольку все данные точки общего доступа хранятся в виде одной таблицы, один запрос в виде списка, который превышает 5000 элементов, заблокирует всю таблицу данных точки общего доступа в этом содержимом. База данных и все пользователи столкнутся с огромным снижением производительности. Всему набору пользователей, использующих Share Point во время эскалации блокировки, придется ждать более длительное время для получения данных. Следовательно, вы можете видеть, что пороговое значение списка является ограничением, которое налагается на Share Point его внутренним SQL Server. Эта проблема возникает из SQL, и причиной является эскалация блокировки строк. Чтобы избежать этого снижения производительности, Share Point ввел ограничение в 5000 элементов, которые должны запрашиваться в любой момент времени. Любые запросы для 5000 элементов будут обработаны пороговым сообщением об ошибке. Ссылка на ссылку

Спасибо

Редактировать____________________________________

Статья по этому вопросу: https://www.c-sharpcorner.com/article/sharepoint-list-threshold-issue-the-traditional-problem /

Комментарии:

1. Привет для моего исследования, это ограничение Sharepoint, а не ограничение sql server, см. Эту ссылку: docs.microsoft.com/fr-fr/previous-versions/office /…

2. Это может помочь, если вы ссылаетесь на то, откуда взята эта цитата (по причинам атрибуции, если нет других). Насколько мне известно, конкретные номера точек останова не задокументированы MS.

3. Вам может помочь другая ссылка: support.office.com/en-us/article /…

4. Короче говоря, слишком широкий запрос приведет к большим проверкам, что серьезно снизит производительность многопользовательской DMS. Конечные пользователи также не могут просматривать 5000 элементов, если только кто-то не пытался использовать список, как если бы это была таблица. В этом случае решающее значение имеет указание правильных индексов

5. SQL Server может предпринять попытку эскалации блокировки после удержания 5000 блокировок для одной ссылки на объект. Смотрите раздел Порог эскалации для инструкции Transact-SQL , но если он не выполняется на более высоком, чем обычно, уровне изоляции, этого не произойдет после чтения 5000 элементов. Вам потребуется как блокировка строк, так и, по крайней мере, повторяемое чтение, чтобы элементы и блокировки были сопоставлены таким образом. При чтении зафиксированные блокировки снимаются, как только данные считываются

Ответ №1:

Блокирует ли SQL Server таблицы, когда запросы возвращают результаты, превышающие 5000 записей?

Как правило, нет.

Документально подтверждено, что 5000 — это магическое число для ядра базы данных для первой попытки эскалации блокировки (с последующими попытками с шагом 1250), но если не выполняется с повторяемым чтением или сериализуемым уровнем изоляции, обычно это не будет достигнуто, просто вернув 50000 элементов в a 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);