SQL Server 2008中的表上的WITH(NOLOCK)

时间:2012-02-27 11:39:31

标签: sql-server sql-server-2008

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

所以我想在桌面上申请申请with(NOLOCK)

我知道

SELECT * FROM temporder with(NOLOCK)

这句话我能做到。但有没有办法从SQL Server 2008直接将with(NOLOCK)应用于表。

3 个答案:

答案 0 :(得分:7)

你的问题的直接答案是否定的 - 没有选择告诉SQL 从不锁定tableX 。话虽如此,你的问题开辟了一系列应该提出来的事情。

隔离级别

首先,最直接的方法是使用with (nolock)选项或SET TRANSACTION ISLOATION LEVEL READ UNCOMMITTED(又称混乱)。这些选项分别适用于查询或连接的持续时间。如果我选择此路由,我会将其与长时间运行的SQL事件探查器跟踪相结合,以识别在TableX上锁定的任何查询。

锁定升级

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

覆盖SQL的锁定escaltion通常不是一个好主意。正如documentation states

  

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

尽管看起来很直观,但从您描述的情景中,可能会有一些运气,而不是NOLOCK。您需要使用实际工作负载来测试此理论,以确定其是否值得。

快照隔离

您还可以查看SNAPSHOT隔离级别。你的问题中没有足够的信息可以知道,但我怀疑它会有所帮助。

NOLOCK的危险

话虽如此,正如你可能从@ GSerg的评论中得到的那样,NOLOCK可能是邪恶的。 No-Lock通俗地称为混沌 - 这是有充分理由的。当开发人员第一次遇到NOLOCK时,似乎允许脏读是唯一的含义。还有更多...

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

但是不要接受我的话:

答案 1 :(得分:2)

您无法更改表或数据库的默认隔离级别(快照除外),但是您可以在一个事务中为所有读取查询更改它:

set transaction isolation level read uncommitted

有关详细信息,请参阅msdn

答案 2 :(得分:2)

这不是表格的配置。

如果在查询中添加(nolock)(它被称为查询提示),则表示在执行此(并且只有此查询)时,它不会在受影响的表上创建锁定。

当然,您可以通过将事务隔离级别设置为未提交读取来保持当前连接的永久配置,例如:set transaction isolation level read uncommitted。但同样,它只在该连接打开之前有效。

也许如果你详细解释一下你想要达到的目标,我们可以更好地帮助你。