ORA-01652 根源多为刷新SQL引发WINDOW SORT等大排序,非磁盘不足;应查执行计划TempSpc列、V$TEMPSEG_USAGE及V$SORT_SEGMENT,建日志复合索引、清理过期日志、设ATOMIC_REFRESH=FALSE,并更新统计信息。
直接改执行路径,别加临时表空间文件——90%的 ora-01652 根源不在磁盘容量,而在刷新 sql 生成了 window sort、sort group by 或 temp table transformation,临时段需求远超连续空闲块。
查清到底是哪步在吃临时空间
别只看 DBA_TEMP_FILES 总大小。物化视图快速刷新实际走的是嵌套 MERGE,中间可能隐含多层临时表转换。关键要看真实执行计划里的 TempSpc 列:
- 用
DBMS_MONITOR.SESSION_TRACE_ENABLE跟踪刷新会话,再用tkprof解析,重点找Operation含WINDOW SORT且TempSpc > 10G的行 - 查
V$TEMPSEG_USAGE关联V$SESSION,确认SQL_ID是否属于MERGE INTO MV_XXX自身,还是底层日志表(如MLOG$_MV_XXX)全表扫描后被迫去重 - 检查
V$SORT_SEGMENT中STATUS = 'ACTIVE'且对应刷新SQL_ID的段——如果blocks持续不降,说明卡在大排序上,不是瞬时峰值
避开 WINDOW SORT 的三个实操动作
物化视图日志(MLOG$)默认按 SNAPTIME$$ 排序合并,一旦日志积压或字段含 CLOB,Oracle 就倾向走 WINDOW SORT 而非索引扫描。这不是配置问题,是执行计划选择偏差:
- 给日志表建复合索引:
CREATE INDEX idx_mlog_snap ON MLOG$_MV_XXX (SNAPTIME$$, CHANGE_VECTOR$$) ONLINE;,避免全表扫日志后排序 - 刷新前清理过期日志:
EXEC DBMS_MVIEW.PURGE_LOG('MV_XXX', 1, 'COMMIT_SCN');,防止WINDOW SORT处理几万行无用变更 - 设
ATOMIC_REFRESH => FALSE:DBMS_MVIEW.REFRESH('MV_XXX', METHOD => 'F', ATOMIC_REFRESH => FALSE);,跳过原子性保障,让 Oracle 直接TRUNCATE再INSERT /*+ APPEND */,避开MERGE里的排序分支
为什么调 PGA_AGGREGATE_TARGET 或 SORT_AREA_SIZE 无效
物化视图刷新走的是服务器进程(server process),不是用户会话,它不读你 ALTER SESSION 设的值。真正起作用的是底层工作区策略和 TEMP 表空间本身配置:
-
SORT_AREA_SIZE在 11g+ 已被废弃,PGA_AGGREGATE_TARGET对刷新过程几乎无影响 - 临时段分配由执行计划驱动,而非会话级内存参数;强行调高只会掩盖问题,不解决排序资源分配策略缺陷
- 真正该动的是日志索引、积压清理、刷新模式,以及基表连接字段是否类型一致、有无隐式转换导致索引失效
最容易被忽略的一点:执行计划过期。统计信息陈旧时,优化器可能为日志表选择全表扫描+排序,而不是索引范围扫描。哪怕语句没变、数据量没突增,也得定期 DBMS_STATS.GATHER_TABLE_STATS,尤其对 MLOG$_* 表和基表。


















