我们的应用程序使用 SQL Server 应用程序锁,并且在某些情况下我们需要查看给定的锁是否存在。为此,我们从 中检索和过滤信息sys.dm_tran_locks
。
这是可行的,但即使是SELECT * FROM sys.dm_tran_locks
我们系统中针对此 DMV 的最简单查询 ( ) 也需要超过 100 毫秒(CPU 和持续时间),有时可能会超过 500 毫秒。这是无论是否以超级管理员用户身份运行、是否从 SSMS 运行时的情况。
full 最多返回大约 10,000 行SELECT
,并且我们在具有充足 CPU 和 RAM 以及快速磁盘子系统的 VM 上运行。这个查询似乎不应该花费这么长时间。
有人以前见过这个或者知道这里可能发生什么吗?如果有帮助的话,我很乐意提供更多信息。
您应该使用
APPLOCK_MODE
和APPLOCK_TEST
而不是扫描 DMV 锁。背景
DMV
sys.dm_tran_locks
本身采用广泛使用的流式表值函数 (sTVF) 接口,该接口通过使用仅限内部OPENROWSET(TABLE ...
语法的 T-SQL 公开。该接口包含用于所有执行引擎迭代器的常用Open
、GetRow
和方法。Close
许多系统功能和视图都使用 sTVF 模式。每个方法如何初始化以及提供对底层数据的一次一行访问的方式根据数据源的不同而有所不同。
下面是这个特定 DMV 的一些示例调用堆栈:
打开
获得行
描述锁的所有者
逻辑稳定锁
锁定资源
关联对象 ID
输出列数据类型
提供给 sTVF 的参数(如果有的话)可以下推到内部数据访问中,也存在一些变化。在支持下推的情况下,行在显示到查询处理器之前会被过滤。
大多数 sTVF 支持将参数作为外部引用传递(例如,由 提供的列值
APPLY
),但并非全部。在几个主要产品版本中,对这方面的支持已经逐渐完善。该文档总结得很好: