PostgreSQL查pg_stat_all_views.last_accessed(需track_counts=on)或pg_stat_statements反向匹配;SQL Server用sys.dm_exec_query_stats关联视图名;MySQL依赖general_log或performance_schema正则提取,须排除维护账号、探测查询及跨库调用盲区。

查哪些视图长期没被访问过
核心是定位「生产环境里创建了但几乎没人用」的视图,这类对象容易成为维护负担或安全隐患。不能只看 CREATE_TIME,得结合实际访问行为。PostgreSQL 和 SQL Server 有运行时统计视图(如 pg_stat_all_views、sys.dm_exec_query_stats),但 MySQL 没有原生视图级访问计数器——得靠慢日志或代理层日志反推。
实操建议:
- PostgreSQL:优先查
pg_stat_all_views的last_accessed(需开启track_counts = on)或用pg_stat_statements关联视图名过滤 SELECT 语句 - SQL Server:用
sys.dm_exec_query_stats+sys.dm_exec_sql_text提取含FROM或JOIN视图名的最近 SQL,注意匹配大小写和 schema 前缀(如[dbo].[v_customer_summary]) - MySQL:必须启用
general_log或用performance_schema.events_statements_history(5.7+),但默认不记录视图名,只能靠正则匹配 SQL 文本里的FROM `v_.*`类模式
怎么定义“孤立”和“长时间”
“孤立”不是指没依赖,而是无业务调用;“长时间”也不能一刀切设为 90 天——得看系统节奏。金融类系统可能 14 天没访问就该预警,而报表类系统季度性使用,阈值得拉到 120 天。
关键判断逻辑:
- 排除 DBA 维护账号(如
'pg_monitor'、'sa')的访问记录,避免误判 - 过滤掉
EXPLAIN、SELECT 1这类探测性查询,它们不反映真实业务使用 - 对多 schema 环境,确认视图是否被其他 schema 的存储过程引用(仅查 SELECT 日志会漏掉)
- 若视图被物化(如 PostgreSQL 的
MATERIALIZED VIEW),其刷新行为不算“用户访问”,要单独处理
告警触发后如何验证是否真可下线
自动标记“疑似废弃”只是第一步,直接 DROP 风险极高。必须做三层交叉验证:
- 查代码仓库:用
git grep -i 'v_customer_summary' -- '*.sql' '*.py' '*.java'扫描所有项目,注意别忽略注释里的旧视图名 - 查调度任务:检查 Airflow DAG、Cron 表达式、SSIS 包里是否隐式调用(比如拼接 SQL 字符串)
- 查应用日志:在 ELK 或 Splunk 中搜
"v_customer_summary"+"ERROR"或"WARN",有时报错日志反而暴露了隐藏调用点 - 临时加审计:对高疑视图开启
AUDIT SELECT ON v_xxx(Oracle)或CREATE POLICY(PG),观察一周是否有新命中
为什么不能只依赖数据库自带的 last_used 字段
很多文档说查 pg_stat_all_views.last_modified 或 sys.views.modify_date 就行——这是典型误区。last_modified 只记录 DDL 变更时间,modify_date 是创建或 ALTER 时间,跟访问完全无关。更坑的是 SQL Server 的 sys.dm_db_index_usage_stats 根本不统计视图,只统计基表。
真正能用的只有运行时执行计划缓存或日志回溯,但这两者都有盲区:缓存会老化清空,日志可能被轮转删掉。所以必须把阈值设成「大于最大日志保留天数 + 7 天」,否则会漏判。
复杂点在于跨库场景——视图 A 在 db1,但被 db2 的存储过程调用,此时 db1 的日志里根本看不到访问痕迹。这种只能靠全链路追踪或定期导出依赖图谱比对。

















