SQL Server 不记录视图的最后访问时间,只能通过执行计划缓存(sys.dm_exec_query_stats 等 DMV)反推;因缓存易被清除且 objectid 常为空,结果不稳定,故不可直接依赖,必须结合依赖检查、重命名观察和业务评估才能安全清理。

sys.dm_exec_query_stats 和 sys.dm_exec_sql_text 是定位“最后访问时间”的核心依据,但必须明确:SQL Server 本身不记录视图的单独访问时间,只能通过查询该视图的执行计划历史反推。直接查 sys.views 或 sys.objects 拿不到访问时间,硬查会误删。
为什么不能直接查视图的“最后使用时间”
SQL Server 不在元数据中维护视图被 SELECT 的时间戳。所谓“最后访问”,本质是某条引用该视图的 SQL 语句最近一次执行的时间——它藏在执行计划缓存里,且只保留近期、高频、未被驱逐的计划。
常见错误是写 SELECT * FROM sys.views WHERE modify_date < '2025-01-01',这查的是视图定义修改时间,不是使用时间,删掉的可能是刚改完但天天在用的视图。
如何用执行计划缓存反推视图使用情况
需关联三张 DMV:sys.dm_exec_query_stats(执行统计)、sys.dm_exec_sql_text(SQL 文本)、sys.dm_exec_cached_plans(缓存计划),再用 OBJECT_NAME() 提取引用对象:
SELECT DISTINCT OBJECT_NAME(st.objectid, st.dbid) AS referenced_view, qs.last_execution_time FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st WHERE st.text LIKE '%your_view_name%' AND st.objectid IS NOT NULL AND st.dbid = DB_ID() ORDER BY qs.last_execution_time DESC;
注意点:
- 该查询结果不稳定:缓存可能被
DBCC FREEPROCCACHE清掉,或因内存压力自动淘汰,查不到不等于没用过 -
st.objectid在跨库引用或动态 SQL 场景下常为NULL,得靠text LIKE模糊匹配,但易误伤(比如视图名是vw_user,而 SQL 里写了user_id) - 必须在目标数据库上下文中执行,否则
DB_ID()和OBJECT_NAME(..., dbid)会错位
安全删除前必须做的三件事
别跳过验证,否则删错视图会导致报表、ETL 或应用报 Invalid object name:
- 检查是否有存储过程/函数/触发器显式依赖:
SELECT * FROM sys.sql_expression_dependencies WHERE referenced_id = OBJECT_ID('your_view') - 临时重命名视图并观察 24–48 小时:
EXEC sp_rename 'old_view', 'old_view_unused_20260423',盯紧应用日志和监控告警 - 确认无定时作业调用:查
msdb.dbo.sysjobs+msdb.dbo.sysjobsteps,搜索视图名(含引号和方括号)
真正能落地的清理流程
把“按最后访问时间删”转成可操作动作,关键是分两步走:
- 先跑一周的缓存采样:每天固定时间执行上面的 DMV 查询,结果插入一张
view_access_log表,加capture_time DATETIME字段 - 一周后查哪些视图从未出现在任何一次采样中,再结合依赖检查和重命名观察,才敢执行
DROP VIEW your_view - 严禁用事件调度器自动删视图——缓存不可靠,自动化只会放大误删风险
复杂点在于:缓存只是线索,不是证据;真正决定删不删的,永远是业务影响评估,不是数据库里某条记录的时间戳。

















