SQL Server不直接记录存储过程最后执行时间,需依赖运行时机制:缓存方案用sys.dm_exec_query_stats关联sql_handle查last_execution_time(最常用),或用Extended Events长期跟踪sp_statement_completed事件(最可靠)。

SQL Server里没有直接记录存储过程最后执行时间的系统视图
SQL Server本身不维护每个存储过程的“最后执行时间”这个元数据。sys.procedures 或 sys.objects 里只有创建/修改时间(create_date、modify_date),跟实际执行无关。想查真实执行时间,必须依赖运行时采集机制。
用查询计划缓存反推最近执行时间(最常用且无需额外配置)
SQL Server会把最近使用过的执行计划缓存在内存中,其中包含 last_execution_time 字段。只要目标存储过程近期执行过、且计划尚未被驱逐出缓存,就能查到近似时间。
实操建议:
- 执行前确保数据库未重启、缓存未被大规模清理(如
DBCC FREEPROCCACHE) - 用
sys.dm_exec_query_stats关联sys.dm_exec_sql_text和sys.dm_exec_cached_plans提取文本和时间 - 过滤条件必须用
object_name+database_id精确匹配,避免误命中同名对象 - 注意:缓存中可能有多个相同存储过程的不同计划(例如不同参数导致的重编译),要取最大值才接近“最后一次”
SELECT TOP 1
qs.last_execution_time
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
WHERE st.objectid = OBJECT_ID('YourStoredProcedureName')
AND st.dbid = DB_ID()
ORDER BY qs.last_execution_time DESC;
启用SQL Server Audit或Extended Events长期跟踪(适合生产环境监控)
缓存方案不可靠——计划随时可能被挤出。若需稳定记录每次执行,必须主动开启跟踪。
推荐选 Extended Events(轻量、低开销):
- 捕获
sp_statement_completed事件,并用object_name过滤目标存储过程 - 避免用
sql_batch_completed,它不区分内部调用层级,容易漏掉嵌套执行 - 务必设置
WHERE object_name = N'YourStoredProcedureName',否则日志爆炸 - 输出目标建议用
event_file,别用环形缓冲区(ring_buffer),后者内存受限易丢数据
注意:audit 方案需要服务器级权限,而 XEvent 只需 ALTER ANY EVENT SESSION,权限更可控。
为什么不能依赖 DMV 中的 execution_count 或 cached_time
sys.dm_exec_procedure_stats 看起来很诱人,但它有几个致命限制:
- 只返回当前仍在缓存中的存储过程统计,一旦计划被清除,整行就消失
-
cached_time是计划加载进缓存的时间,不是执行时间;last_execution_time字段在 SQL Server 2016+ 才有,旧版本根本不存在 - 该 DMV 不包含数据库上下文信息,跨库同名存储过程无法区分
- 默认不开启收集,首次查询前需执行过至少一次,且未被清空过缓存
所以,别把它当“可靠来源”,它只是缓存方案的一个补充视角,不能替代上面两种方法。
真正可靠的方案永远是提前布防——要么用 XEvent 持续捕获,要么在关键存储过程中手动写日志表。临时翻缓存,本质是在赌运气。

















