无效。Oracle 不允许在 ALTER TABLE 中直接修改 FREELISTS,会报 ORA-02243 错误,因其为段级属性,仅在建表或重建段时生效;必须通过 MOVE、CTAS 或 DBMS_REDEFINITION 等方式重建段才能生效。

ALTER TABLE 时直接加 FREELISTS 有效吗
无效。Oracle 不允许在 ALTER TABLE 中修改 FREELISTS,执行会报错:ORA-02243: ALTER INDEX or ALTER TABLE statement not allowed for this object。这是因为 FREELISTS 是段(segment)级属性,只在对象创建或重建时生效,运行时无法动态调整。
必须重建表才能生效的三种方式
要让 FREELISTS 生效,本质是重建段结构。常用且安全的做法有:
-
ALTER TABLE ... MOVE TABLESPACE <same_ts> STORAGE (FREELISTS n):最常用,不改表空间也能触发段重建,STORAGE子句中指定FREELISTS即可 -
CREATE TABLE ... AS SELECT+DROP+RENAME:适合需同时调整其他存储参数(如PCTUSED)的场景,但需停写窗口 -
DBMS_REDEFINITION:在线重定义,适用于不能停业务的表,但要求主键或唯一约束,且过程较重
注意:MOVE 操作会失效索引,需后续重建;FREELISTS 值建议不超过 CPU 核心数 × 2,过高反而增加管理开销。
MSSM 下 FREELISTS 和 FREELIST GROUPS 的关系
二者不是互斥而是协同作用:
-
FREELISTS控制每个 freelist 链上能挂多少块(即单个链的深度) -
FREELIST GROUPS控制有多少条独立的 freelist 链(即并发插入通道数) - 实际可用空闲块 =
FREELIST GROUPS×FREELISTS,但 Oracle 内部有上限(通常 ≤ 255) - 若只设
FREELISTS不设FREELIST GROUPS,默认为 1 组;反之亦然
高并发插入场景下,优先调大 FREELIST GROUPS(如设为 CPU 数),再按需配 FREELISTS(通常 2–5 足够)。
ASSM 表空间里设 FREELISTS 会怎样
完全被忽略。即使你在建表语句里写了 STORAGE (FREELISTS 8),只要表所在表空间是 ASSM(查 DBA_TABLESPACES.SEGMENT_SPACE_MANAGEMENT = 'AUTO'),Oracle 就不会记录该参数,也不会报错——它静默丢弃。
验证方法:
SELECT segment_name, freelists FROM dba_segments WHERE segment_name = 'YOUR_TABLE';
结果中 FREELISTS 列始终为 NULL 或 0,就是 ASSM 在起作用。
真正需要调优的只有 PCTFREE,其他空间参数全交给位图管理。别在 ASSM 环境下白费力气配 FREELISTS。


















