为什么过程有时会挂起执行 SELECT...INTO #Temp2 FROM #Temp1 JOIN LocalTable...?

Mar*_*man 6 performance sql-server stored-procedures insert sql-server-2012

我们有几个由作业调用的存储过程,它们遵循特定的模式(旨在最小化阻塞)。其中一些 proc 有时会挂起,运行 CPU、tempdb 分配、读取和写入,直到被终止。图案是:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
CREATE #RemoteTemp...;
INSERT INTO #RemoteTemp EXEC MyLinkedServer.DbName.SchemaName.ProcName;
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
SELECT...INTO #MixedTemp FROM #RemoteTemp JOIN LocalTable...;
Run Code Online (Sandbox Code Playgroud)

然后我们使用#MixedTemp. 但是,最后一条语句有时会在不到一秒的时间内运行,有时会挂起,即使每次执行的行数都相同。什么可能导致这种情况?

附加信息:

  • 1117 和 1118 已启用。
  • 这个 8 核实例的 8 个 tempdb 文件。
  • 没有发生 tempdb 自动增长。

挂起期间:

  • Sch-S 锁定本地表。
  • 在正在读取的临时表上:

    Lock resource_type="HOBT.BULK_OPERATION" request_mode="S"
    request_status="GRANT" request_count="1" Lock resource_type="OBJECT"
    request_mode="X" request_status="GRANT" request_count="1"
    
    Run Code Online (Sandbox Code Playgroud)
  • 在插入的临时表上:

    Lock resource_type="OBJECT"
     request_mode="X" request_status="GRANT" request_count="1"
    
    Run Code Online (Sandbox Code Playgroud)

从 sp_lock(6 和 7 是连接到临时表的数据库,2 是 tempdb):

spid   dbid   ObjId       IndId  Type Resource                         Mode     Status
------ ------ ----------- ------ ---- -------------------------------- -------- ------
96     6      0           0      DB                                    S        GRANT
96     7      0           0      DB                                    S        GRANT
96     6      702625546   0      TAB                                   Sch-S    GRANT
96     2      -1219105587 0      HBT  [BULK_OPERATION]                 S        GRANT
96     7      98099390    0      TAB                                   Sch-S    GRANT
96     2      -1219105587 0      TAB                                   X        GRANT
96     2      -1203105530 0      TAB                                   X        GRANT
96     7      115775811   0      TAB                                   Sch-S    GRANT
96     7      194099732   0      TAB                                   Sch-S    GRANT
Run Code Online (Sandbox Code Playgroud)

Pau*_*ite 6

提供的错误计划 XML showplan显示查询中的两个表具有指示的零行(计划中的其他对象很好):

零基数

SQL Sentry Plan Explorer的 Plan Tree view 中捕获

这可能是由于自动更新统计数据的问题,或者可能是由于在快照隔离下运行的一些怪癖。确实没有足够的信息可以说。无论如何,这是您应该调查的事情。

如果表和索引统计信息确实丢失(或为空),手动构建这些统计信息几乎肯定会解决您所看到的问题。

给定不正确的信息,查询优化器会生成一个具有嵌套循环连接的计划:

NLJ计划

当运行时行数大大超过 QO 计划的数时,此计划有可能执行很长时间。查询没有被阻止;它只是继续使用有缺陷的策略执行。

当合理的统计数据可用时生成的“好计划”会生成一个使用散列连接和并行性的执行计划:

好计划