每个分区必须显式指定独立表空间且数据文件须分布于不同物理磁盘或ASM diskgroup,否则I/O集中导致性能下降;共用USERS表空间会使所有分区争抢同一数据文件,引发缓冲区争用和高等待事件。

直接说结论:每个分区必须显式指定独立表空间,且这些表空间的数据文件要分布在不同物理磁盘或ASM diskgroup上;否则“分区”只是逻辑切分,I/O 依然打在同一组数据文件上,性能不升反降。
为什么不能让所有分区共用 USERS 表空间?
常见错误现象是建完12个按月分区,却没写 TABLESPACE,结果全落到 USERS——查 dba_tab_partitions 看起来每个分区都有记录,但 tablespace_name 全是 USERS,而 dba_data_files 里它只挂了一个超大文件(比如 /u01/oradata/db/users01.dbf)。这时所有分区的读写争抢同一文件头、同一 checkpoint queue,缓冲区争用加剧,v$segment_statistics 里能看到大量 gc buffer busy acquire 或 db file sequential read 等待。
真正起作用的不是“分区数量”,而是底层数据文件的物理分布。如果 USERS 只有一个 datafile,那无论你分100个区还是1个区,I/O 路径都一样。
- 检查方式:
SELECT tablespace_name, COUNT(*) FROM dba_data_files GROUP BY tablespace_name—— 若某表空间 count = 1,就存在单点风险 - 不要依赖
DEFAULT TABLESPACE:用户级默认表空间只影响未显式指定TABLESPACE的对象,对分区无效 - 本地索引也必须和对应分区同表空间:否则查询剪枝失效,执行计划里出现
INLIST ITERATOR或全分区扫描
怎么为每个分区创建对应的表空间?
关键不是“建多少”,而是“怎么命名+怎么配参数”。命名要能反映分区维度和时间粒度(比如 TBS_SALES_2024_Q1),避免用模糊名如 TBS_PART1;参数要差异化,尤其 INITIAL 和 NEXT 必须按单个分区预估,不能套用原表总大小。
示例(按季度建):
CREATE TABLESPACE TBS_SALES_2024_Q1 DATAFILE '/u02/oradata/db/sales_q1_01.dbf' SIZE 8G AUTOEXTEND ON NEXT 512M MAXSIZE 32G EXTENT MANAGEMENT LOCAL AUTOALLOCATE SEGMENT SPACE MANAGEMENT AUTO; CREATE TABLESPACE TBS_SALES_2024_Q2 DATAFILE '/u03/oradata/db/sales_q2_01.dbf' SIZE 8G AUTOEXTEND ON NEXT 512M MAXSIZE 32G EXTENT MANAGEMENT LOCAL AUTOALLOCATE SEGMENT SPACE MANAGEMENT AUTO;
-
DATAFILE路径必须跨磁盘:/u02 和 /u03 应指向不同物理盘或 ASM diskgroup -
INITIAL至少设 8G(≈8388608000 字节),不是 1MB;高频写入分区建议设更大(如 20G) -
NEXT设为INITIAL的 10%~20%,避免频繁扩展导致 extent 碎片(设 64KB 是典型踩坑) - 必须加
SEGMENT CREATION IMMEDIATE:否则首次 INSERT 才分配段,可能触发延迟等待
建分区时如何绑定表空间?
在 CREATE TABLE ... PARTITION BY RANGE 语句中,每个 PARTITION 子句必须显式带 TABLESPACE,不能省略,也不能指望父表或用户默认表空间继承。
错误写法(被忽略):PARTITION sales_q1 VALUES LESS THAN (...) TABLESPACE DEFAULT
正确写法:
CREATE TABLE sales (
id NUMBER,
sale_date DATE,
amount NUMBER
) PARTITION BY RANGE (sale_date) (
PARTITION sales_q1 VALUES LESS THAN (DATE '2024-04-01')
TABLESPACE TBS_SALES_2024_Q1,
PARTITION sales_q2 VALUES LESS THAN (DATE '2024-07-01')
TABLESPACE TBS_SALES_2024_Q2,
PARTITION sales_q3 VALUES LESS THAN (DATE '2024-10-01')
TABLESPACE TBS_SALES_2024_Q3,
PARTITION sales_max VALUES LESS THAN (MAXVALUE)
TABLESPACE TBS_SALES_ARCHIVE
);
- 漏写任意一个
TABLESPACE,该分区就会落到当前用户的DEFAULT TABLESPACE(通常是USERS) - 历史归档分区可单独用低速盘表空间(如
TBS_SALES_ARCHIVE),但 OLTP 主分区务必高速盘 - 新增分区必须用
ALTER TABLE ... ADD PARTITION ... TABLESPACE xxx显式指定,不能省略
最容易被忽略的验证点:物理隔离是否真实成立?
很多人跑完 CREATE TABLESPACE 和 CREATE TABLE ... PARTITION 就认为搞定了,但没验证底层 datafile 是否真分散。查 dba_segments 看到每个分区有独立 segment_name,不代表物理隔离;查 dba_tab_partitions 看到 tablespace_name 不同,也不代表 I/O 分散——最终要看 dba_data_files 中这些表空间是否各自挂载了独立 datafile,且路径指向不同存储设备。
验证命令:
SELECT p.partition_name, p.tablespace_name, d.file_name, d.bytes/1024/1024/1024 GB FROM dba_tab_partitions p JOIN dba_data_files d ON p.tablespace_name = d.tablespace_name WHERE p.table_name = 'SALES' ORDER BY p.partition_name;
- 若多个分区的
tablespace_name相同,但file_name路径相同 → 物理未隔离 - 若
file_name路径不同,但都在同一 RAID 组或同一 ASM diskgroup 条带下 → 仍可能争抢 - 真正安全的做法:每个热分区表空间只挂一个 datafile,且该 datafile 独占一块物理盘或专属 ASM failgroup











