在我的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/