是否每次ALTER PROCEDURE都需添加WITH RECOMPILE?遇执行异常求助
问题背景
- 遇到异常问题,考虑通过给存储过程添加
WITH RECOMPILE解决 - 核心疑问:每次编写
ALTER PROCEDURE脚本时,有没有理由不包含WITH RECOMPILE? - 额外异常现象:
- 用完全相同的参数调用存储过程,SSMS执行结果与网站执行结果不一致
- 弹出错误提示:
System.Data.SqlClient.SqlException: The definition of object 'SP name' has changed since it was compiled.
但存储过程的输入输出参数、结果集并未做任何修改 - SQL Server配置存在问题:同一子网内同时设置了DHCP和静态IP
- 存储过程每日调用约20次,优先保证结果准确性而非性能
回答
要不要每次ALTER都加WITH RECOMPILE?
答案是不需要每次都加,核心原因如下:
- 无意义的资源浪费:虽然你的存储过程调用频率不高,性能影响有限,但
WITH RECOMPILE会让存储过程每次执行都重新生成执行计划。后续如果调用量上升,编译开销会持续累积;哪怕当前调用量低,重复编译也是对数据库资源的不必要消耗。 - 掩盖根本问题:你遇到的“同参数结果不一致”“定义变更错误”,本质大概率和SQL Server的IP配置冲突(DHCP+静态IP导致网络身份、会话缓存异常)、执行计划缓存污染有关。直接全局加
WITH RECOMPILE可能暂时压下表面问题,但会隐藏真正的配置错误,后续可能引发更难排查的故障。 - 有更精准的替代方案:如果确实需要强制重新编译,没必要在
ALTER PROCEDURE里全局加:- 单次调用强制编译:
EXEC SP_name @param1 = ... WITH RECOMPILE;,适合临时排查问题 - 特定语句强制编译:给存储过程中出问题的查询单独加
OPTION (RECOMPILE),避免全局编译开销 - 手动清空单个SP缓存:执行
EXEC sp_recompile 'SP_name';,修改SP后跑一次就能让后续调用生成新计划,无需在ALTER脚本里加参数
- 单次调用强制编译:
针对你的异常现象的建议
- 优先修复IP配置:同时启用DHCP和静态IP会导致SQL Server的网络身份识别混乱,极有可能是“定义变更错误”“结果不一致”的核心诱因。先把IP改成单一模式(要么静态要么DHCP),再观察问题是否消失。
- 排查执行计划缓存:用
sys.dm_exec_cached_plans和sys.dm_exec_sql_text查看该存储过程的缓存计划,确认是否存在过时或异常的计划。如果发现异常,调用sp_recompile手动清除缓存。 - 验证结果一致性:修复IP配置后,用相同参数分别在SSMS和网站端执行,同时捕获执行计划和执行上下文,对比两者的执行路径是否一致,确认结果差异是否消除。
内容的提问来源于stack exchange,提问作者Chris Mathews
相关产品推荐
相关产品推荐

