我有一个 SP,他的执行时间在四天内从 5 分钟 > 20 分钟 > 30 分钟 > 53 分钟
等待显示 CPU 增加和挂起状态
我隔离了一个与 CPU 挂钩的查询
UPDATE thing.table
SET YYYYMM =
CASE
WHEN
DAY(SnapshotDate) = 1
OR
SnapshotDate = (SELECT MAX(SnapshotDate) FROM thing.table)
THEN CAST(FORMAT(DATEADD(day,-1,snapshotdate),'yyyyMM') AS INT)
ELSE NULL
END
我再次运行它,WITH (RECOMPILE)
在最后添加 - 没有区别
我跑了UPDATE STATISTICS thing.table
- 没有区别
运行它并获得实际计划会很有趣,但我不想让 CPU 挂一个小时。我检查了sys.dm_exec_cached_plans
,但似乎只有估计的计划,没有实际的计划
我重写了 usingCONVERT
而不是FORMAT
(因为我对新事物持怀疑态度)——没有区别
所以我这样重写并将执行时间缩短到几秒钟:
BEGIN TRAN;
UPDATE thing.table
SET YYYYMM = NULL;
UPDATE thing.table
SET YYYYMM = CAST(FORMAT(DATEADD(day,-1,snapshotdate),'yyyyMM') AS INT)
WHERE
(
DAY(SnapshotDate) = 1
OR
SnapshotDate = (SELECT MAX(SnapshotDate) FROM thing.table)
);
COMMIT TRAN;
该表中有大约 150,000 条记录。很可能它最近有更多的记录被倾倒在其中,扭曲统计数据,但为什么会WITH(RECOMPILE)
而UPDATE STATISTICS
不是修复它呢?它需要每日快照,并且可能由于月底而增加的记录数量。
所以问题是:
- 实际查询计划是否存储在任何地方?以节省我以交互方式运行它?
- 通常当查询突然永远耗时时,它会过时统计但这里似乎不是这种情况
这是我的 SQL Server 版本
Microsoft SQL Server 2014 - 12.0.4100.1 (X64) Apr 20 2015 17:29:27 Copyright (c) Microsoft Corporation Standard Edition (64-bit) on Windows NT 6.3 (Build 9600: ) (Hypervisor)
以下是慢速和快速查询计划。毫不奇怪,它们是不同的,因为它们在做不同的事情:
慢计划:
快速计划:
我注意到 slowpoke 使用循环连接,而 fasty 使用哈希匹配。
我注意到循环连接的小腿有过滤器
[Expr1006]=DB.thing.table.[SnapshotDate]
. 也许那不再那么小了?