oracle 19c表空间默认压缩必须用default compress basic或for oltp,row store compress非法;alter tablespace default compress for oltp可在线执行但仅影响新建表,建表时仍需显式声明压缩才生效。
直接启用表空间级默认压缩,再建表时显式声明或依赖继承,是最稳妥的压缩落地方式;但仅设表空间 default compress for oltp 不等于表自动压缩——建表语句里漏掉压缩声明,表照样不压缩。
CREATE TABLESPACE 时指定 DEFAULT COMPRESS 失败?别写 ROW STORE COMPRESS
Oracle 19c 不识别 ROW STORE COMPRESS 作为 DDL 关键字。它只是文档里的泛称,不是合法语法。一写就报 ORA-00922: missing or invalid option。
- ✅ 正确写法:
CREATE TABLESPACE ts_comp DEFAULT COMPRESS FOR OLTP - ✅ 或:
CREATE TABLESPACE ts_comp DEFAULT COMPRESS BASIC - ❌ 错误写法:
CREATE TABLESPACE ts_comp ROW STORE COMPRESS FOR OLTP - ⚠️ 注意:BASIC 压缩只对
INSERT /*+ APPEND */、CREATE TABLE AS SELECT生效;OLTP 压缩才支持单行 INSERT/UPDATE
ALTER TABLESPACE 启用默认压缩后,老表为什么没变小?
ALTER TABLESPACE ... DEFAULT COMPRESS FOR OLTP 只影响后续新建的表,已有表结构和数据块完全不受影响——哪怕你执行 ALTER TABLE t MOVE,也不会自动重压缩。
- 要压缩已有表,必须显式执行:
ALTER TABLE t COMPRESS FOR OLTP(或MOVE COMPRESS FOR OLTP) -
MOVE操作会重建段、释放空闲空间,但需注意:它会锁表,且期间索引失效,得重建 - 验证是否生效:查
USER_TABLES的COMPRESSION和COMPRESS_FOR字段,不能只看 DDL 语句
建表时不写 COMPRESS,表空间默认设置会生效吗?
不会。即使表空间设了 DEFAULT COMPRESS FOR OLTP,只要建表语句中没提压缩,Oracle 就按默认 NOCOMPRESS 处理。
- ✅ 继承默认:
CREATE TABLE t (x INT)—— 实际启用 OLTP 压缩(前提是表空间设了默认) - ❌ 显式关闭:
CREATE TABLE t (x INT) NOCOMPRESS—— 强制不压缩 - ✅ 最明确写法:
CREATE TABLE t (x INT) COMPRESS FOR OLTP—— 清晰可控,不依赖上下文 - ⚠️ 容易被忽略:分区表每个分区可单独指定压缩,全局设置不自动覆盖分区级定义
压缩后空间反而变大?PCTFREE 和数据分布是关键
压缩不是万能的,尤其当表原本就很稀疏、或 PCTFREE 设得过高(如默认 10),压缩后可能因块内重组失败导致链式行增多,实际占用更大。
- 对以查询为主、极少更新的表,可考虑调低
PCTFREE(比如设为 1 或 0)再压缩 - 高并发 UPDATE 场景下,
COMPRESS FOR OLTP会尝试在更新时重组行,可能引发enq: TX - row lock contention或buffer busy waits - 务必在测试环境压测真实业务负载,重点关注
db file sequential read和chained rows指标











