Oracle 19c中ROW STORE COMPRESS不是合法DDL关键字,故表空间创建时无效;真正有效的是DEFAULT COMPRESS子句,且必须明确指定BASIC或FOR OLTP类型。
表空间级压缩必须显式指定 compress for oltp 或 compress basic,不能靠 row store compress 关键字自动生效。
为什么 ROW STORE COMPRESS 在表空间创建时无效
Oracle 19c 中没有 ROW STORE COMPRESS 这个独立语法。它是某些文档或 GUI 工具对「行存储压缩」的笼统描述,不是 DDL 支持的关键字。直接在 CREATE TABLESPACE 语句里写它会报错:ORA-00922: missing or invalid option。
真正起作用的是 DEFAULT COMPRESS 子句,且必须搭配明确的压缩类型:
-
DEFAULT COMPRESS BASIC:仅对INSERT /*+ APPEND */、CREATE TABLE AS SELECT等批量操作生效 -
DEFAULT COMPRESS FOR OLTP:对单行INSERT/UPDATE也生效,是 OLTP 场景唯一推荐的表空间级压缩方式
ALTER TABLESPACE ... DEFAULT COMPRESS FOR OLTP 的实操要点
已存在的表空间可通过 ALTER TABLESPACE 启用默认压缩,但注意:
- 该设置只影响后续新创建的表,已有表不受影响(哪怕
MOVE也不会自动重压缩) - 执行前确保数据库兼容性参数
compatible≥'12.2.0'(19c 默认满足) - 若表空间含非空数据文件且处于读写状态,命令可在线执行,无需停机
- 验证是否生效:查
DBA_TABLESPACES的COMPRESS_FOR列,应为OLTP
示例:
ALTER TABLESPACE users DEFAULT COMPRESS FOR OLTP; SELECT tablespace_name, compress_for FROM dba_tablespaces WHERE tablespace_name = 'USERS';
新建表时仍需显式声明压缩,否则可能不压缩
即使表空间设了 DEFAULT COMPRESS FOR OLTP,如果建表语句中写了 NOCOMPRESS 或完全没提压缩,Oracle 仍按默认不压缩处理 —— 这是容易被忽略的关键点。
- ✅ 正确(继承表空间默认):
CREATE TABLE t1 (x INT); - ❌ 不压缩(显式覆盖):
CREATE TABLE t1 (x INT) NOCOMPRESS; - ✅ 显式启用(更明确):
CREATE TABLE t1 (x INT) COMPRESS FOR OLTP;
检查表是否实际启用压缩,别只信 DDL:查 USER_TABLES 的 COMPRESSION 和 COMPRESS_FOR 字段。
OLTP 压缩对 DML 性能的真实影响
高级行压缩(FOR OLTP)不是零成本的。它在每次 UPDATE 时尝试重组行内空闲空间,可能引发链式行(chained rows)或额外的 buffer busy waits。
- 高并发
UPDATE密集型表(如订单状态表),建议先在测试环境压测db file sequential read和enq: TX - row lock contention等等待事件 - 压缩后段大小减少 ≠ 查询变快;若频繁全表扫描且 buffer cache 不足,IO 减少才体现收益;否则 CPU 解压开销可能抵消 IO 节省
-
ALTER TABLE ... MOVE COMPRESS FOR OLTP可重压缩存量数据,但会锁表且产生大量 redo,避免在业务高峰执行
真正省空间又低风险的场景,其实是归档表或历史分区 —— 那里更适合用 COMPRESS FOR ARCHIVE LOW,但该特性仅限 Exadata 硬件支持。











