【问题标题】:How to avoid non unique Clustered index in deadlocks如何避免死锁中的非唯一聚集索引
【发布时间】:2017-06-10 15:31:40
【问题描述】:

我有没有主键的表。但它在 4 列上有非唯一聚集索引。在更新表中的一个非键列时,我们看到这个索引是死锁的一部分。 我们怎样才能避免这种情况?创建具有 5 列的主键还是添加标识列更好?删除现有的聚集索引后,我们可能还需要创建非聚集索引以提高性能。

【问题讨论】:

  • 我想到了很多解决方案(身份 + 非聚集索引,身份 + 包含复合 PK 的非聚集索引)。答案取决于您的要求和数据结构。他们唯一的共同点是:你应该给桌子一个PK。现有信息无法回答您的问题。

标签: sql indexing sql-server-2012 database-deadlocks


【解决方案1】:

解决死锁的最佳资源(仍然)在这里:https://docs.microsoft.com/en-us/archive/blogs/bartd/deadlock-troubleshooting_2c00_-part-1

第 4 点说:

通过数据库调优运行涉及死锁的查询 顾问。在 Management Studio 查询窗口中添加查询,更改 db 上下文到正确的数据库,右键单击查询文本并 选择“分析 DTA 中的查询”。不要跳过这一步;半数以上 我们看到的死锁问题中的大多数只需添加一个 适当的索引,以便其中一个查询运行得更快,并且 具有更小的锁占用空间。如果 DTA 推荐索引(它会说 “估计改进:%”),创建它们并监控 看看死锁是否仍然存在。您可以选择“应用建议” 从操作下拉菜单中立即创建索引,或者 将 CREATE INDEX 命令保存为脚本,以便在 维护窗口。请务必分别调整每个查询。

我知道这并不能“回答”为什么必然的问题,但它确实表明添加索引可以改变执行方式,使锁占用更小或执行时间更快,这可以显着减少死锁。

https://stackoverflow.com/a/10738827/7462678

【讨论】:

  • 谢谢LS!!我尝试运行 DTA,我选择了导致死锁的整个 MERGE 语句,但它在建议中没有显示任何内容。
  • 我创建了一个新的标识列并创建了主键和聚集索引。将现有的聚集索引更改为非聚集索引。现在在 lock-mode = X 的聚集索引上发生死锁。我们如何避免这种情况? Web 服务创建多个线程并调用具有此合并语句导致死锁的 SP。
  • 只有一种(简单)方法可以 100% 确保您不会在此过程中陷入死锁,那就是向 MERGE 添加 TABLOCKX 提示,但这可能会非常糟糕对性能的影响。添加 TABLOCK 提示可能足以解决问题,而不会对您的性能产​​生很大影响。最后,您还可以尝试添加 PAGLOCK、XLOCK 或同时添加 PAGLOCK 和 XLOCK。同样,这可能会起作用,性能可能不会太糟糕。您必须尝试才能看到。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-04
  • 2019-02-23
  • 1970-01-01
  • 2019-10-28
  • 1970-01-01
  • 2013-06-07
  • 2012-08-14
相关资源
最近更新 更多