atomic_refresh => FALSE必须与parallelism配对使用,否则并行无效;需先执行ALTER SESSION ENABLE PARALLEL DML,且日志结构(ROWIDS、SEQUENCE、PRIMARY_KEY全为YES)和物化视图定义(不含GROUP BY/JOIN)均需满足FAST刷新条件。

DBMS_MVIEW.REFRESH 太慢,90% 不是 SQL 本身的问题,而是底层资源争用、参数没配对、日志结构不支持或调度卡住。直接调大 parallelism 或改刷新频率,大概率白忙。
为什么 atomic_refresh => FALSE 必须和 parallelism 一起用
parallelism 参数在 atomic_refresh => TRUE(默认)下完全无效——所有并行进程挤在一个事务里等提交,锁、undo、TX 等待全来了。
只有设成 FALSE,Oracle 才真正分批提交(如每 5 万行 commit 一次),释放并行能力。
- 必须在同一会话中先执行 ALTER SESSION ENABLE PARALLEL DML,再调用 DBMS_MVIEW.REFRESH
- atomic_refresh => FALSE 对 method => 'C' 和 'F' 都生效,但对 'FAST' 刷新无影响
- 若物化视图含 GROUP BY、JOIN 或聚合函数,该参数会被 Oracle 忽略,悄悄退回到原子模式
- 刷新期间 MV 可能短暂返回新旧混合数据,业务查询需容忍此窗口
怎么确认日志表 MLOG$_xxx 没拖后腿
哪怕 SELECT COUNT(*) FROM MLOG$_your_table 返回 0,也不代表它没膨胀——高水位线(HWM)悬空才是真问题。
- 查真实空间占用:SELECT bytes/1024/1024 AS mb FROM dba_segments WHERE segment_name = 'MLOG$_YOUR_TABLE'
- 如果 MB 远大于实际行数,执行:ALTER TABLE MLOG$_YOUR_TABLE ENABLE ROW MOVEMENT,再 ALTER TABLE MLOG$_YOUR_TABLE SHRINK SPACE COMPACT
- 检查日志是否支持 FAST:SELECT ROWIDS, SEQUENCE, PRIMARY_KEY FROM USER_MVIEW_LOGS WHERE MASTER = 'YOUR_TABLE',三者必须全为 YES
- 多表 JOIN 场景下,每个基表都要有独立日志,且 SEQUENCE() 中必须包含 JOIN 列和 ROWID
AWR 里怎么看刷新到底卡在哪
AWR 默认 60 分钟快照,若刷新耗时短于这个周期,根本捕不到——得临时调小快照间隔或查 v$active_session_history。
- 先定位 DBMS_MVIEW.REFRESH 对应的 SQL ID,再查它的 Top Event:重点关注 enq: TX - row lock contention、log file sync、direct path write temp
- 查执行计划:SELECT operation, options FROM v$sql_plan WHERE sql_id = 'xxx' AND operation = 'LOAD TABLE CONVENTIONAL' —— 出现就说明 INSERT /*+ APPEND */ 没走通,降级为常规插入
- 若 SQL ordered by CPU Time 中同一 SQL ID 的 Executions = 1,基本是串行;若 Parallel Servers Started 列有值,才算真并行
- LOB 字段会暴露异常:Buffer Gets/Row 远高于同类 MV(常达 1000+),执行计划里出现 LOB WRITE 或 LOB Locator,此时并行基本失效
别让调度器成为最后一根稻草
很多“刷新慢”其实是作业压根没跑起来。
- 查 DBA_JOBS 或 DBA_SCHEDULER_JOBS:确认 BROKEN = 'N'、NEXT_DATE 是否滞后数小时
- job_queue_processes 默认常为 10,若同时有 15 个 MV 刷新作业排队,实际间隔远超设定
- Oracle 12c+ 强烈建议迁移到 DBMS_SCHEDULER,并绑定 RESOURCE_CONSUMER_GROUP 控制 CPU 资源份额
- 避免模糊调度表达式如 FREQ=DAILY,改用精确 START_DATE 和 REPEAT_INTERVAL => 'FREQ=SECONDLY; INTERVAL=300'
真正卡点往往藏在 atomic_refresh 是否生效、日志表 HWM 是否悬空、AWR 是否捕到真实 SQL、以及调度器是否已排队——这些地方一漏,调参就全是空中楼阁。











