必须将索引与表分置不同表空间以实现物理隔离、缓解磁盘争用;高并发OLTP下同盘I/O寻道加剧等待,Oracle官方建议分置物理磁盘;新建索引表空间需LOCAL管理、AUTO段空间、独立路径及合理MAXSIZE。
为什么必须把索引和表分到不同表空间
不是为了“看起来规范”,而是物理隔离能直接缓解磁盘争用。当一个查询既要读表数据块、又要读索引块时,如果它们在同一个数据文件甚至同一块磁盘上,磁头就得来回寻道——尤其在高并发 oltp 场景下(比如收银系统 80+ 连接同时查库存),i/o 等待会明显抬高 db file sequential read 等待事件。oracle 官方文档明确建议:数据表空间与索引表空间应置于不同物理磁盘。
创建索引表空间的实操要点
别直接复用 USERS 或 SYSTEM 表空间。新建专用索引表空间时注意:
-
EXTENT MANAGEMENT LOCAL必须启用,这是 Oracle 9i+ 的标准做法,避免字典管理带来的争用 - 推荐使用
SEGMENT SPACE MANAGEMENT AUTO,由 Oracle 自动管理位图,比MANUAL更稳定 - 初始大小按预估索引总量设(例如 2GB),但
AUTOEXTEND ON NEXT 100M MAXSIZE UNLIMITED要谨慎——生产环境建议设MAXSIZE上限,防止失控增长挤占磁盘 - 路径要落在独立物理盘(如
/u02/oradata/db/index01.dbf),不能和主数据文件共用/u01
示例语句:
CREATE TABLESPACE idx_tbs DATAFILE '/u02/oradata/db/idx01.dbf' SIZE 2G AUTOEXTEND ON NEXT 100M MAXSIZE 20G EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;
把已有索引迁移到新表空间
迁移不是一蹴而就,容易踩三个坑:
- 用户在目标表空间没配额 → 执行
ALTER USER username QUOTA UNLIMITED ON idx_tbs,否则报ORA-01950: no privileges on tablespace 'idx_tbs' - 重建索引期间锁表 →
REBUILD ONLINE可减少阻塞,但要求企业版;标准版只能停写窗口操作 - 索引重建后状态为
UNUSABLE→ 检查SELECT index_name, status FROM user_indexes,失败的需重试或加PARALLEL参数分摊压力
批量生成迁移脚本常用:
SELECT 'ALTER INDEX ' || index_name || ' REBUILD TABLESPACE idx_tbs;' FROM user_indexes WHERE tablespace_name != 'IDX_TBS';
哪些索引不该放独立表空间
不是所有索引都值得单独规划:
- 小表(
- 频繁更新的字段上的索引(如订单状态列),写放大严重,与其拆表空间,不如先评估是否真需要这个索引
- 位图索引(
CREATE BITMAP INDEX)通常用于只读数据仓库,I/O 模式和 B* 树不同,一般不强制分离,反而常和事实表放在同组高速盘
真正该优先分离的,是大表(>1GB)上的复合索引、主键索引、外键索引——这些才是 I/O 热点。


















