【问题标题】:SQL Server 2012: why different values in where clause would block a select query?SQL Server 2012:为什么 where 子句中的不同值会阻止选择查询?
【发布时间】:2017-06-12 01:31:45
【问题描述】:

我们的应用程序执行这两个查询:

select   A.* from   LETTUREAPERTE A
where IDAZIENDAOPERATORE=3

select   A.* from   LETTUREAPERTE A
where IDAZIENDAOPERATORE=2

根据用户正在考虑的公司 ID。 好吧,虽然第二个查询正确执行,但第一个查询阻塞并且永远不会执行。 LETTUREAPERTE 表中的记录少于 400 条,有的有 IDAZIENDAOPERATORE 有 2 条,有的有 3 条。

我不知道为什么会发生这种情况以及为什么第一个查询会阻塞...最后我得到了这个错误我得到一个错误,说进程被选为死锁牺牲品。

事务(进程 ID 62)与另一个进程在锁资源上死锁,并已被选为死锁牺牲品。重新运行事务。

我什至运行了一些查询来检测该表的某些记录上是否存在一些更新锁,但没有。这一定是因为在整个项目中我们从未在查询中使用过UPDLOCK...

【问题讨论】:

  • with option (recompile)看看有没有更好的执行计划。
  • 嗯,我应该在哪里添加with option (recompile)?这是什么声明?
  • select A.* from LETTUREAPERTE A where IDAZIENDAOPERATORE=2 with option(recompile)..但我认为这不会影响有 400 条记录的表。你能发布死锁图吗
  • 我得到相同的结果...有时需要 80 秒才能执行。正如我之前所说的那样,它有时会中止......
  • 你可以把执行计划贴在这里分享给大家:brentozar.com/pastetheplan

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


【解决方案1】:

尝试运行 Adam Mechanic 的 sp_WhoIsActive 并跟踪可能使用相同表源的事务。之后在sp_lock(系统一)中找到这个对象。基于此,您应该了解为什么会出现这种僵局。 在执行期间,值 2 可能与值 3 没有被相同的(锁定的)索引使用 - 这在对表使用过滤索引时是可能的。

【讨论】:

  • 请原谅,我无法从文档中了解如何使用这些程序...如果我运行exec sp_WhoIsActive,它会说这样的程序不存在。我对这些商店的程序几乎一无所知...
  • link - 您可以在作者博客上找到所需的一切。在基础上 - 只需在没有任何参数的情况下执行它,这将向您显示 SQL Server 实例上的所有活动事务及其会话 ID。根据该 ID,您可以执行“sp_lock”link 以查看受影响的对象(基本上是查看您是否正在尝试访问当前被另一个进程使用的对象。
  • 我会看看...我不知道是否允许我下载和安装外部库,因为上周我们在第二个生产服务器中安装了一个加密锁...我会问致我的开发团队负责人
  • 这是 DBA 最常用和认可的一种 ;-) 如果不尝试至少内置的“sp_who2” - 这个将向您展示所有内容(除了查询本身)并且您必须自己过滤它,因为这也包括系统事务。
  • 我刚刚运行了此处链接的查询 (sqlservergeeks.com/sys-dm_tran_active_transactions),我注意到有 6 小时前开始的 6 个只读/仅活动事务...我应该关闭它们吗?跨度>
【解决方案2】:

一种可能性是在带有3 的行上的未提交/未回滚事务。

如果使用事务,您需要使用 TRY/CATCH 并提交或回滚。

你可以试试(NOLOCK):

select   A.* from   LETTUREAPERTE A (NOLOCK)
where IDAZIENDAOPERATORE=3

另一种选择是重新启动 SQL Server 以查看是否可以解决问题,但很可能会再次发生

【讨论】:

  • 即使我在查询中使用(NOLOCK) 我得到相同的结果......我不知道是否有应该删除的阻塞事务。有没有办法得到这个?
  • 感谢您的帮助。我已经尝试过该查询,并且检查过没有未结交易...
【解决方案3】:

正如 Gordon 在评论中建议的那样,添加选项重新编译,如下所示

select   A.* from   LETTUREAPERTE A
where IDAZIENDAOPERATORE=2 OPTION (RECOMPILE)

【讨论】:

  • 我得到相同的结果...有时需要 80 秒才能执行。正如我之前所说的,有时它会中止......
  • 您错过了option 之前的with 关键字,不确定是不是选项?!
  • 从 10 分钟前开始,我再也没有出现任何错误……执行起来确实需要太多时间。总是在 70/80 秒左右,每个人都向我抱怨应用程序很慢......
  • @Tanner 正如你所说,它是可选的
  • 可以分享一下执行计划吗?
【解决方案4】:

正如** Bartosz X** 向我建议的那样,我为参与视图的每个表启动了以下命令:

UPDATE STATISTICS [Schema].[Table_Name] WITH FULLSCAN

花了大约一个小时才完成,但情况似乎有了很大改善。 因此,我添加了以下维护计划,每周执行一次:

如果有兴趣,这是我的观点的查询:

SELECT        
  IDOPERATORE, 
  COGNOMENOMEOPERATORE, 
  IDAZIENDAOPERATORE,
  (SELECT
     SUM(LETTURERIMASTE) AS Expr1
   FROM dbo.LETTURERIMASTE AS B
   WHERE (IDLOTTOLETTURISTA IN
           (SELECT IDLOTTOLETTURISTA
            FROM dbo.LOTTILETTURISTA AS C
            WHERE (DATAFINELOTTOLETTURISTA >= CONVERT(datetime, ROUND(CONVERT(float, GETDATE()), 0, 1))) AND (IDLETTURISTALOTTOLETTURISTA = A.IDOPERATORE)))) 
   AS LETTURERIMASTE

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-30
    • 1970-01-01
    • 2014-09-29
    • 2019-06-25
    • 2014-11-04
    相关资源
    最近更新 更多