位图索引重建必须先执行 ALTER INDEX ... UNUSABLE,再 REBUILD,最后收集统计信息;不支持 ONLINE、COALESCE 和 SHRINK,且重建后需手动 Gather Index Stats 以避免执行计划劣化。
位图索引重建前必须先设为不可用
直接 alter index ... rebuild 对位图索引会失败,报 ora-01408: column list already indexed 或静默跳过——因为位图索引不支持在线原地重建。必须分三步走:先置为不可用,再重建,最后验证可用性。这和b树索引的 rebuild online 完全不同,不能省略 unusable 步骤。
-
ALTER INDEX idx_name UNUSABLE;是强制前提,否则后续重建会被拒绝 - 执行后该索引立即失效,查询计划可能退化为全表扫描,务必避开业务高峰
- 如果索引被约束(如唯一位图索引)依赖,
UNUSABLE会直接报错,需先禁用约束
重建时用 REBUILD 而非 COALESCE
位图索引不支持 COALESCE(该命令对位图索引无效果,执行后 DBA_SEGMENTS.BYTES 不变)。真正释放空间的是 REBUILD ——它会丢弃旧段、分配新段,并重写压缩后的位图块。
- 重建后段大小通常下降 30%~60%,尤其在低基数列(如状态码、性别)上效果明显
- 不要加
ONLINE:位图索引不支持REBUILD ONLINE,加了会报ORA-01702: a view is not appropriate here - 若要加速,可加
PARTITION子句(针对分区表)或PARALLEL 4,但需确认临时表空间充足
重建后必须收集索引统计信息
位图索引重建后,DBA_INDEXES 中的 NUM_ROWS、LEAF_BLOCKS 等字段仍为旧值,CBO 可能误判选择率,导致执行计划劣化(比如不该走索引却走了,或反之)。
- 必须立刻执行:
EXEC DBMS_STATS.GATHER_INDEX_STATS('OWNER', 'IDX_NAME'); - 避免用
GATHER_TABLE_STATS代替——它不会刷新位图索引的内部位图分布统计 - 若重建前刚做过
ANALYZE INDEX ... VALIDATE STRUCTURE,重建后该操作结果已失效,无需重做
注意位图索引段的空间回收边界
即使重建成功,段大小也不会低于该索引逻辑所需的最小物理块数。例如一个只有 3 个值的列,重建后段可能仍占几百 MB——这不是失败,而是位图块按“值范围+ROWID区间”编码的固有开销。
- 用
SELECT segment_name, bytes/1024/1024 mb FROM dba_segments WHERE segment_name = 'IDX_NAME';对比重建前后 - 若空间未明显下降,检查是否误建在 ASSM 表空间且
PCTFREE过高;位图索引建议设PCTFREE 0(建索引时指定) - 别指望像 B 树索引那样通过
SHRINK SPACE进一步压缩——位图索引段不支持SHRINK


















