查询返回的结果大于5000条记录时,SQL锁定表是否存在?

时间:2019-04-16 14:33:08

标签: sql-server sharepoint

我正在使用SharePoint,并且试图了解为什么列表中视图的数目最多可以多于5000条记录。

我的问题不是关于SharePoint,而是关于SQL。 SQL是否具有下面描述的限制,或者这是SharePoint团队对SQL施加的限制?

  

出于性能原因,每当SQL Server执行单个查询时   返回5000多个项目,SQL内发生锁升级   表。结果,整个表将被锁定。由于整个   共享点数据存储为单个表,单个列表视图查询   超过5000+项将锁定整个共享点数据表   在该内容内。数据库和所有用户将面临巨大的挑战   性能下降。使用Share Point的整个用户组   锁定升级的时间将需要等待更长的时间才能   检索数据。因此,您可以看到列表阈值是   后端SQL Server对Share Point施加的限制。   此问题是从SQL生成的,原因是行锁定   升级。为了避免这种性能下降,请共享   Point已限制任何情况下要查询的5000件物品   时间点。对5000个以上商品的任何查询将被处理为阈值   错误信息。引用链接

谢谢

EDIT ____________________________________

有关此问题的文章: https://www.c-sharpcorner.com/article/sharepoint-list-threshold-issue-the-traditional-problem/

1 个答案:

答案 0 :(得分:1)

  

查询返回的结果大于5000时,SQL Server锁定表是否   记录?

一般来说,不是。

is documented的数字是5,000,这是数据库引擎首先尝试进行锁定升级的魔幻数字(随后以1,250的增量进行进一步尝试),但是除非以可重复读取或可序列化的隔离级别运行,否则通常不会被击中通过在SELECT中返回5,0000个项目。默认的读取提交级别将在读取数据后立即释放锁定,因此请不要超过阈值。

通过以下示例,您可以看到隔离级别对此的影响。

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);