几个星期以来,我一直在与我们服务器上的一个持续问题作斗争。有一个简单的查询可以在几个不同的存储过程中运行,但在其中一些存储过程中,查询可能需要将近 4 分钟才能运行。一些过程具有完全相同的查询,并且它们在 < 1 秒内运行。从查询窗口运行它会在 < 1 秒内返回。
我无法重新创建它 - 我无法运行用户正在运行的过程(因为它会更改数据),并且我们的测试服务器上不会出现问题。我有时可以重新编译(F5)该过程,这似乎重新创建了执行计划,并修复了一段时间,但它总是返回。
查询很简单:
SELECT '1'
FROM TRANSACTION_LOG WITH (NOLOCK)
WHERE TYPE = 15 AND SERIAL_NO = @P_TRAVELER_SERIAL
TRANSACTION_LOG
有 ~90m 行TYPE
有一个非聚集索引SERIAL_NO
有一个非聚集索引
经过一些研究和分析器捕获后,我在执行计划中发现了一些奇怪的东西。我设法在快速运行时捕获执行计划,在运行缓慢时捕获另一个执行计划。这些来自完全相同的过程,完全相同的查询 - 唯一的区别是@P_TRAVELER_SERIAL
参数的值:
快速地:
Compute Scalar(DEFINE:([Expr1005]=CASE WHEN [Expr1006] THEN (1) ELSE (0) END))
|--Nested Loops(Left Semi Join, DEFINE:([Expr1006] = [PROBE VALUE]))
|--Constant Scan
|--Filter(WHERE:([MICS].[dbo].[Transaction_Log].[TYPE]=(15)))
|--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1000], [Expr1010]) WITH UNORDERED PREFETCH)
|--Index Seek(OBJECT:([MICS].[dbo].[Transaction_Log].[IX_SERIAL_NO]), SEEK:([MICS].[dbo].[Transaction_Log].[SERIAL_NO]=[@P_TRAVELER_SERIAL]) ORDERED FORWARD)
|--RID Lookup(OBJECT:([MICS].[dbo].[Transaction_Log]), SEEK:([Bmk1000]=[Bmk1000]) LOOKUP ORDERED FORWARD)
慢的:
Compute Scalar(DEFINE:([Expr1005]=CASE WHEN [Expr1006] THEN (1) ELSE (0) END))
|--Nested Loops(Left Semi Join, DEFINE:([Expr1006] = [PROBE VALUE]))
|--Constant Scan
|--Table Scan(OBJECT:([MICS].[dbo].[Transaction_Log]), WHERE:([MICS].[dbo].[Transaction_Log].[TYPE]=(15) AND [MICS].[dbo].[Transaction_Log].[SERIAL_NO]=[@P_TRAVELER_SERIAL]))
为什么它会在一个计划中使用索引查找,而在另一个计划中使用表扫描?这是相同的查询和相同的程序?表活动与它有什么关系吗?这是一张繁忙的桌子...
谢谢