在我的SQL tempOrder表中有数百万条记录,并具有10个触发器以使用另一个表的更新来更新tempOrder表。

所以我想在表上应用apply with(NOLOCK)

我知道

SELECT * FROM temporder with(NOLOCK)

我可以做到这一点。但是有什么方法可以将with(NOLOCK)直接应用于SQL Server 2008中的表。

最佳答案

您问题的直接答案是“否”-没有选择告诉SQL永远不要锁定tableX。话虽如此,您的问题提出了应提出的一系列问题。

隔离度

首先,完成目标所需的最直接方法是使用with (nolock)选项或SET TRANSACTION ISLOATION LEVEL READ UNCOMMITTED(又名混乱)。这些选项分别适合查询或连接持续时间。如果选择此路由,则将其与长时间运行的SQL Profiler跟踪结合使用,以标识对TableX进行锁定的所有查询。

锁升级

其次,SQL Server确实具有表范围的LOCK_ESCALATION阈值(执行为ALTER TABLE SET LOCK_ESCALATION x,其中X是锁的数量或AUTO)。这可以控制SQL何时尝试将许多细粒度的锁合并为较少的粗粒度的锁。换句话说,它是一个数字阈值,用于转换在单个数据库对象(思考索引)上获取多少个锁。

覆盖SQL的锁升级通常不是一个好主意。作为documentation states


在大多数情况下,数据库引擎可在以下情况下提供最佳性能
使用其默认设置进行锁定和锁定升级。


看起来似乎很不直观,但从您描述的情况来看,您可能会遇到一些幸运的情况,即使用NOLOCK较少的广泛锁定。您需要用实际的工作量来检验该理论,以确定它是否值得。

快照隔离

您也可以检查SNAPSHOT隔离级别。您的问题中没有足够的信息要知道,但是我怀疑这会有所帮助。

NOLOCK的危险

话虽如此,您可能已经从@GSerg的评论中受益,NOLOCK可能是邪恶的。无锁通俗地称为混沌-这是有充分理由的。当开发人员第一次遇到NOLOCK时,似乎只允许脏读。还有更多...


读取脏数据以获取不一致的结果(常见的印象)
错误的数据-意味着与数据的写入前或写入后状态均不一致。
终止查询的硬异常(例如由于数据移动导致的错误601)
返回空白数据
先前提交的行被遗漏
返回格式错误的字节


但不要相信我:


Actual Email: "NoLOCK is the epitome of evil?"
SQL Sever NOLOCK hint & other poor ideas
Is the nolock hint a bad practice

关于sql-server - SQL Server 2008中表上的WITH(NOLOCK),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9464394/

10-11 03:38