【问题标题】:What is the purpose of ROWLOCK on Delete and when should I use it?删除时 ROWLOCK 的目的是什么,我应该什么时候使用它?
【发布时间】:2011-03-01 15:54:30
【问题描述】:

例如)

我什么时候应该使用这个语句:

DELETE TOP (@count)
FROM ProductInfo WITH (ROWLOCK)
WHERE ProductId = @productId_for_del;

什么时候应该做:

DELETE TOP (@count)
FROM ProductInfo
WHERE ProductId = @productId_for_del;

【问题讨论】:

  • 除非你真的有你并且知道可能的后果是什么,否则不要使用提示。

标签: sql sql-server


【解决方案1】:

Rowlock 是一种查询提示,应谨慎使用(所有查询提示也是如此)。

省略它可能仍会导致完全相同的行为,并且提供它并不能保证它只会使用行锁,毕竟它只是一个提示。如果您对锁争用没有非常深入的了解,那么优化器可能会选择最佳的锁定策略,而这些事情通常最好留给数据库引擎来决定。

ROWLOCK 表示 SQL 在执行删除时将只锁定受影响的行,而不是整个表或表中存储数据的页。这只会影响在删除运行的同时从表中读取的其他人。

如果使用了表锁,它将导致对表的所有查询等到您的删除完成,而行锁仅选择读取特定行将被等待。

在任何情况下,删除前 N 个(其中 N 是行数)很可能会锁定表。

【讨论】:

    【解决方案2】:

    with (rowlock) 是一个提示,它指示数据库它应该在行范围内保持锁定。这意味着数据库将避免将锁升级到块或表范围。

    当查询只影响一行或几行时,您使用提示,以防止锁锁定不会被查询删除的行。这将让另一个查询同时读取不相关的行,而不必等待删除完成。

    如果您在将删除大量行的查询上使用它,它可能会降低性能,因为数据库会尽量避免将锁升级到更大的范围,即使它会更有效。

    通常您不需要在查询中添加此类提示,因为数据库知道要使用哪种锁。只有在由于数据库做出错误决定而导致性能问题的情况下,您才应该将此类提示添加到查询中。

    【讨论】:

    • 您是否建议在循环中一次删除 2000 行的删除语句中使用它?
    • 数据库应该能够自行做出决定。如果它认为有充分的理由,它将升级。我会避免推翻它(这是提示的作用),除非我有充分的理由,比如我知道数据库不知道的东西。
    • @Brandon:是的,这是一个很好的观点。通常,数据库知道要使用什么锁,这比程序员要好得多。
    • 在另一个索引列和多个线程中执行未覆盖的删除时,您可能会发现此提示很有用。在我的情况下,我正面临多个导致页面锁定的死锁。不幸的是,mssql 2012 决定在我的案例中忽略提示并再次进行页面锁定。我以禁用聚集索引上的页面锁结束。
    • Hints: “由于 SQL Server 查询优化器通常会为查询选择最佳执行计划,因此我们建议仅将提示用作经验丰富的开发人员和数据库管理员的最后手段。”
    猜你喜欢
    • 2011-01-18
    • 2011-08-18
    • 2017-03-21
    • 2010-09-05
    相关资源
    最近更新 更多