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. 但是,最后一条语句有时会在不到一秒的时间内运行,有时会挂起,即使每次执行的行数都相同。什么可能导致这种情况?
附加信息:
挂起期间:
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)
提供的错误计划 XML showplan显示查询中的两个表具有指示的零行(计划中的其他对象很好):
从SQL Sentry Plan Explorer的 Plan Tree view 中捕获
这可能是由于自动更新统计数据的问题,或者可能是由于在快照隔离下运行的一些怪癖。确实没有足够的信息可以说。无论如何,这是您应该调查的事情。
如果表和索引统计信息确实丢失(或为空),手动构建这些统计信息几乎肯定会解决您所看到的问题。
给定不正确的信息,查询优化器会生成一个具有嵌套循环连接的计划:
当运行时行数大大超过 QO 计划的数时,此计划有可能执行很长时间。查询没有被阻止;它只是继续使用有缺陷的策略执行。
当合理的统计数据可用时生成的“好计划”会生成一个使用散列连接和并行性的执行计划: