Oracle 19c中可动态启用或禁用Deferred Segment Creation,无需重启数据库;该参数仅影响新建对象,对已存在的空表无效,需手动执行ALLOCATE EXTENT补段。

禁用或启用 Deferred Segment Creation 在 Oracle 19c 中完全可行,且无需重启数据库 —— 但要注意:该参数只影响后续新建的对象,对已存在的空表无任何作用。
如何查看当前 deferred_segment_creation 设置
直接查参数值即可确认是否启用:
show parameter deferred_segment_creation
返回结果中 VALUE 列为 TRUE 表示启用(默认),FALSE 表示已禁用。
- 该参数是动态参数,支持
ALTER SYSTEM或ALTER SESSION修改 - 普通用户无法修改系统级参数,需具备
ALTER SYSTEM权限(如 DBA 角色) - 在 19c 中该参数行为与 11g/12c 一致,未被废弃或变更语义
禁用 Deferred Segment Creation(全局生效)
执行以下命令可让之后所有新建的表、索引等对象立即分配 segment:
ALTER SYSTEM SET deferred_segment_creation = FALSE;
这样做的效果是恢复到传统建表行为:
- 创建空表时即生成
USER_SEGMENTS记录 - 避免
exp工具漏导空表的问题(expdp不受影响) - 外键约束下能正常执行
TRUNCATE TABLE(否则会报 ORA-02449 错误) - 不改变已有空表的状态:之前
segment_created = 'NO'的表仍保持无段状态
为已有空表手动分配 segment
即使禁用了参数,历史遗留的空表仍需单独处理才能拥有 segment。常用方法有:
- 插入再删除一行:
INSERT INTO table_name VALUES (...); COMMIT; DELETE FROM table_name; COMMIT;—— 简单但可能触发业务逻辑或触发器 - 更安全的方式是执行:
ALTER TABLE table_name ALLOCATE EXTENT;—— 不改动数据,仅强制创建初始区(extent) - 批量生成语句可查:
SELECT 'ALTER TABLE ' || table_name || ' ALLOCATE EXTENT;' FROM user_tables WHERE segment_created = 'NO'; - 注意:若表上有未验证的外键,
ALLOCATE EXTENT仍可成功;但TRUNCATE在无 segment 时会静默“成功”,实则未清空(这是最易踩的坑)
建表时临时覆盖参数值
不改全局参数,也能对单个对象控制 segment 创建时机:
- 立即创建:
CREATE TABLE t1 (id NUMBER) SEGMENT CREATION IMMEDIATE; - 延迟创建:
CREATE TABLE t2 (id NUMBER) SEGMENT CREATION DEFERRED;(等同于默认行为) -
SEGMENT CREATION子句优先级高于deferred_segment_creation参数 - 该语法在 19c 中完全支持,且对分区表、IOT 等同样有效
真正容易被忽略的是:哪怕你把参数设为 FALSE,如果忘了给旧空表补 ALLOCATE EXTENT,它们在 exp、TRUNCATE、甚至某些 DBA 脚本中依然表现异常 —— 这类对象就像数据库里的“幽灵表”,看不见 segment,却处处受限。


















