LAST_REFRESH_DATE不可靠,必须结合STALENESS判断:仅STALENESS='FRESH'才表示数据最新可用;STALENESS='STALE'/'UNUSABLE'/'NEEDS_COMPILE'时,即使LAST_REFRESH_DATE非空也意味着数据过期或失效。
LAST_REFRESH_DATE 字段不可靠,不能单独用来判断物化视图是否可用或数据是否最新。
这个字段只记录「最后一次成功完成刷新」的时间点。失败、中断、取消、甚至手动调用 DBMS_MVIEW.REFRESH 后抛出异常,它都不会更新。常见误判场景包括:
STALENESS = 'STALE':刷新失败或未完成,但 LAST_REFRESH_DATE 还是旧值,数据已过期STALENESS = 'UNUSABLE':依赖对象损坏(如日志表被删、DBLink 断开),查询直接报错,时间字段却可能非空STALENESS = 'NEEDS_COMPILE':基表改了 DDL 但没执行 ALTER MATERIALIZED VIEW ... COMPILE,新列查不到,时间字段也可能有值LAST_REFRESH_DATE IS NULL:该物化视图从未成功刷新过只有 STALENESS = 'FRESH' 才代表数据最新且可查;其他值都意味着风险。推荐用这条语句一次性确认:
SELECT mview_name, last_refresh_date, staleness, refresh_mode, refresh_method FROM USER_MVIEWS WHERE mview_name = 'YOUR_MV_NAME';
注意两个关键字段:
refresh_mode 是 DEMAND 还是 COMMIT:决定你对“应该什么时候刷新”的预期refresh_method 是 COMPLETE 还是 FAST:关系到日志是否存在、能否真正走增量USER_MVIEWS 不存失败详情。自动刷新靠 DBMS_SCHEDULER 的,错误在 USER_SCHEDULER_JOB_RUN_DETAILS 里;手动刷新没捕获异常的话,错误直接抛出,不留痕。
查最近失败的刷新任务(适用于 scheduler):
SELECT log_date, job_name, error#, additional_info FROM USER_SCHEDULER_JOB_RUN_DETAILS WHERE status = 'FAILED' AND job_name LIKE '%YOUR_MV_NAME%' ORDER BY log_date DESC FETCH FIRST 5 ROWS ONLY;
ERROR# 是 Oracle 错误号(如 12008、60),ADDITIONAL_INFO 含完整 ORA-xxxx 和触发语句,是定位根因的关键。
真正要确认物化视图能不能用,别盯着时间戳——STALENESS 值和调度日志里的错误信息,比 LAST_REFRESH_DATE 多出的那几个小时更关键。