with recompile 是窄口径救急手段,非提速默认开关;盲目使用引发高频硬解析、cpu 暴涨;仅适用于参数动态拼接等极少数场景,且须置于 as 前;exec 时加仅影响单次执行;语句级 option (recompile) 更精准高效;sp_recompile 仅标记下次刷新,副作用小;多数性能问题根源在统计信息或索引,而非缓存本身。

WITH RECOMPILE 不是“让存储过程变快”的默认开关,而是应对参数分布失控、统计信息严重滞后或临时救急的窄口径手段。盲目加它,反而会触发高频硬解析,导致 CPU 暴涨、并发下降。
CREATE PROCEDURE 时加 WITH RECOMPILE 会怎样
每次执行都丢弃旧计划、从头编译整个过程,完全绕过计划缓存。
- 适用场景极窄:比如 BI 工具动态拼列名 + 时间范围,且每天只跑几次
- 不适用于常规业务过程:高并发下
sys.dm_exec_query_stats中total_worker_time会明显跳升 - 写错位置等于白忙:必须放在
AS前,例如CREATE PROCEDURE uspSearch @key NVARCHAR(50) WITH RECOMPILE AS;写在EXEC后面无效
EXEC 时加 WITH RECOMPILE 的真实用途
只影响这一次调用,不改过程定义,适合 DBA 手动干预卡死或计划异常的单次执行。
- 命令形如:
EXEC uspSearch 'abc123' WITH RECOMPILE - 不能写进应用代码:应用层硬编码这个选项,等于把性能风险常态化
- 权限要求明确:调用者需有该过程的
EXECUTE权限,但不需要对过程定义本身做修改
语句级用 OPTION (RECOMPILE) 更精准
只重编译当前 SELECT/UPDATE 等语句,还能把本地变量当常量优化(比如 @id = 123 直接走索引查找),开销远低于过程级重编译。
- 示例:
SELECT * FROM Orders WHERE Status = @status OPTION (RECOMPILE) - 它能感知过程内
DECLARE @x INT = 100这类变量值,而WITH RECOMPILE不能 - 注意:带
OPTION (RECOMPILE)的语句无法被查询存储的“优化计划强制”功能捕获
别忘了 sp_recompile 这个轻量标记
它不立即重编译,只是给过程打个“下次执行前刷新计划”的标记,真正编译发生在下一次 EXEC 时。
- 命令:
EXEC sp_recompile 'uspSearch' - 适合场景:刚建完新索引、刚
UPDATE STATISTICS完,想让过程尽快用上新统计信息 - 副作用小:不会立刻抢 CPU,也不影响当前正在运行的会话
- 注意:它对视图、触发器也生效,但对 Azure Synapse Analytics 专用池无效
真正难的不是选哪个命令,而是判断要不要重编译——多数“慢过程”问题根源在统计信息陈旧、参数嗅探失准或缺失索引,而不是计划缓存本身。加 WITH RECOMPILE 前,先查 sys.dm_exec_query_stats 和 SET STATISTICS XML ON 输出,否则很可能越修越慢。











