必须在建表时为每个分区显式指定TABLESPACE,漏掉任何一个就会落入用户默认表空间(通常是USERS),导致I/O无法分散、冷热数据干扰;Oracle不会自动按分区逻辑分配表空间。
必须在建表时为每个分区显式指定 tablespace,漏掉任何一个,它就会悄悄落到用户默认表空间(通常是 users),i/o 无法分散,冷热数据互相干扰——这不是配置没生效,而是根本没配。
建表时每个 PARTITION 都要带 TABLESPACE
Oracle 不会自动按分区逻辑分配表空间。哪怕你已经创建了 ts_2024_q1、ts_2024_q2 等多个专用表空间,只要建表语句里某个 PARTITION 子句没写 TABLESPACE,它就归入当前用户的默认表空间。
常见错误写法:
CREATE TABLE sales ( id NUMBER, sale_date DATE ) PARTITION BY RANGE (sale_date) ( PARTITION p_2024_q1 VALUES LESS THAN (DATE '2024-04-01'), PARTITION p_2024_q2 VALUES LESS THAN (DATE '2024-07-01') TABLESPACE ts_2024_q2 );
上面的 p_2024_q1 没指定表空间 → 落入 USERS,后续所有优化都白搭。
正确写法必须全覆盖:
- 每个
PARTITION后紧跟TABLESPACE xxx - 不能用变量或模板省略;不能依赖“以后再搬”
- 建表后立刻查
USER_TAB_PARTITIONS.TABLESPACE_NAME确认是否全部落位
MOVE PARTITION ONLINE 是补救手段,但有硬限制
如果表已上线、分区早已落在默认表空间,可以用 ALTER TABLE ... MOVE PARTITION ... ONLINE 迁移单个分区。但它不是万能钥匙:
- 仅 Oracle 12.1.0.1 及以上支持;11g 或更低版本直接报错
ORA-00922: missing or invalid option - 不支持含
LOB列的分区在线迁移(会触发ORA-14647),必须拆成两步:先主表在线搬,再单独处理LOB段 -
UPDATE INDEXES ONLINE必须带上,否则全局索引会瞬间变UNUSABLE,查询可能直接走全表扫描 - 迁移后
DBA_TAB_PARTITIONS.NUM_ROWS变为NULL,必须立刻执行DBMS_STATS.GATHER_TABLE_STATS(..., GRANULARITY => 'PARTITION')
多个分区批量迁移?别硬扛,用 DBMS_REDEFINITION
想一次把 p_2022* 全部挪到归档表空间?MOVE PARTITION 逐个执行太慢,且锁窗口叠加风险高。Oracle 12.2+ 推荐走联机重定义:
- 调用
DBMS_REDEFINITION.CAN_REDEF_TABLE(..., part_name => 'p_2022_q1,p_2022_q2')验证可行性 - 中间表必须是非分区表,且分别建在目标表空间(如
int_p22q1在ts_archive_2022) - 启用
continue_after_errors => TRUE,避免单个分区失败中断整个流程 - 过程会产生多个临时段和大量 UNDO/REDO,务必提前检查
DBA_REDEFINITION_STATUS和空闲空间
表空间配置差异比“分开了”更重要
只是把分区塞进不同表空间还不够。真正发挥物理隔离价值,得让表空间本身具备差异化能力:
- 热分区(如最近 3 个月):SSD 表空间 +
AUTOEXTEND ON NEXT 100M MAXSIZE 50G+FLASH_CACHE DEFAULT - 温分区(1–2 年前):SAS 表空间 +
AUTOEXTEND ON NEXT 500M MAXSIZE 200G+FLASH_CACHE NONE - 冷分区(3 年以上):NL-SAS 表空间 +
AUTOEXTEND OFF+ 可选READ ONLY - 所有表空间
EXTENT MANAGEMENT LOCAL AUTOALLOCATE和SEGMENT SPACE MANAGEMENT AUTO必须一致,否则跨分区查询可能报ORA-14257
最容易被忽略的是:表空间底层存储路径是否真分散在不同磁盘组?如果 /oradata/ts_2024_q1.dbf 和 /oradata/ts_2024_q2.dbf 实际映射到同一 RAID 卷,I/O 竞争照旧发生。


















