重建全局索引需排序全量键值以构建有序B+树,若PGA不足则溢出至TEMP表空间;并行、ONLINE、小PGA、大基数键值及DML并发均加剧TEMP消耗。

重建全局索引(ALTER INDEX ... REBUILD)会大量占用临时表空间,不是因为“索引数据被存进去了”,而是Oracle在重建过程中必须做排序——索引键值必须严格有序,而重建时需对全量键值重新排序、构建B+树结构。这个排序过程一旦超出PGA容量,就会溢出到TEMP表空间。
为什么REBUILD要排序?
Oracle B树索引的物理结构依赖键值有序性。重建不是简单复制,而是:读取原索引或基表所有键值 → 按升序/降序重排 → 分块填充新叶节点 → 构建分支节点。即使原索引已有序,Oracle也不复用旧结构,而是走完整排序建树流程。
- 默认使用
SORT_AREA_SIZE(11g前)或PGA_AGGREGATE_TARGET控制内存排序区;若键值总量 > 排序内存上限,就写入TEMP - 全局索引通常跨多个分区,键值范围大、重复少(高基数),排序开销远高于本地索引
-
REBUILD ONLINE更甚:需维护日志、捕获DML变更,额外生成排序中间结果用于合并
哪些参数和操作会让TEMP暴涨更明显?
以下配置或动作会显著放大临时空间需求:
-
PGA_AGGREGATE_TARGET设得太小(比如仅256MB),而索引含千万级键值,几乎必然溢出 - 未指定
NOSORT(仅当确认键值物理顺序与索引顺序完全一致时才安全使用) - 加了
PARALLEL N:每个并行进程独立申请排序区,TEMP总用量 ≈ 单进程 × N - 重建时基表正在被大量DML修改:
REBUILD ONLINE需将变更日志与原键值合并排序,中间结果翻倍
如何避免TEMP爆满导致DDL失败?
核心思路是“控量 + 分流 + 预估”:
- 执行前查键值量:
SELECT num_rows FROM user_tables WHERE table_name = 'YOUR_TABLE';,预估排序内存需求(一般1000万键值约需800MB PGA) - 临时调大
PGA_AGGREGATE_TARGET(如从512MB→2GB),重建完成再调回(注意SGA会相应压缩) - 改用
REBUILD ONLINE NOLOGGING减少重做,但需确保归档可接受风险 - 超大索引分批重建:先
ALTER INDEX ... UNUSABLE,再用DBMS_PARALLEL_EXECUTE按主键范围分段REBUILD PARTITION(仅适用于分区索引)
最容易被忽略的是:REBUILD过程中如果遇到唯一键冲突或空间不足报错,已分配的TEMP段不会自动释放,会持续占着直到会话断开。所以生产环境务必在低峰期执行,并监控V$SORT_SEGMENT和V$TEMPSEG_USAGE实时用量。


















