oracle 12c+表空间不支持默认压缩策略,因create/alter tablespace语法根本不识别default compress子句,会报ora-02236或静默忽略;压缩必须在建表或alter table时显式指定compress for子句,且依赖advanced compression许可和底层硬件支持。
oracle 12c 表空间本身不能设默认压缩策略,段级压缩必须在建表或改表时显式指定,且 advanced compression 许可未启用时 compress for 语法会静默降级为 basic 压缩,实际不生效。
为什么 ALTER TABLESPACE 无法设置 default compress
Oracle 12c+ 的 CREATE TABLESPACE 和 ALTER TABLESPACE 语句根本不支持 DEFAULT COMPRESS FOR OLTP 或 DEFAULT COMPRESS FOR QUERY LOW 这类子句。执行会直接报 ORA-02236 或被忽略——表空间不是压缩策略的载体。
真正起作用的是:
- 建表/分区/物化视图时写的
COMPRESS FOR ...子句(如COMPRESS FOR QUERY LOW) - 表空间底层属性,比如 ASM diskgroup 的
compatible.asm版本是否 ≥12.1 -
DEFERRED_SEGMENT_CREATION是否为 TRUE(影响空表是否立即分配段)
如何确认 Advanced Compression 许可已启用
没开许可,COMPRESS FOR QUERY LOW 看似执行成功,实则按 BASIC 压缩处理,完全跳过 HCC 的列级字典和深度编码逻辑,块大小和查询性能都不会改善。
必须查 V$OPTION:
SELECT VALUE FROM V$OPTION WHERE PARAMETER = 'Advanced Compression';
返回值必须是 TRUE。若为 FALSE,所有 COMPRESS FOR 都无效。
验证是否真走 HCC:
- 查
USER_TABLES.COMPRESSION和USER_TABLES.COMPRESS_FOR:值为'ENABLED'不代表 HCC,必须是'QUERY LOW'、'ARCHIVE HIGH'等具体类型 - 运行扫描后查
V$SEGMENT_STATISTICS:physical reads direct显著偏高,说明读的是压缩块
对现有表启用 HCC 压缩的实操路径
ALTER TABLE ... MOVE COMPRESS FOR QUERY LOW 是最常用方式,但极易踩坑:
- MOVE 过程中表会被加
EXCLUSIVE锁(非只读),DML 会阻塞 - 需要临时等量空闲空间:MOVE 先建新压缩段,再删旧段,表空间剩余空间必须 ≥ 当前
DBA_SEGMENTS.BYTES - 不会自动重建索引,需额外
ALTER INDEX ... REBUILD,否则索引仍指向旧数据位置
替代方案是 DBMS_REDEFINITION,适合大表在线操作,但流程更重,需提前建中间表、校验一致性、同步增量。
注意:COMPRESS FOR OLTP(即 ROW STORE COMPRESS ADVANCED)适用于频繁 DML 的 OLTP 表;COMPRESS FOR QUERY LOW/HIGH 属于 HCC,仅适用于全表扫描多、DML 少的 DSS 场景,且必须跑在 Exadata 或 Oracle Cloud Infrastructure 上才真正启用硬件加速解压逻辑。
索引压缩与表压缩是独立控制的
表启用了 HCC,索引不会自动压缩。索引需单独启用高级压缩:
- 创建时:
CREATE INDEX idx ON t(a,b) COMPRESS ADVANCED LOW; - 重建时:
ALTER INDEX idx REBUILD COMPRESS ADVANCED HIGH;
关键限制:
- 单列唯一索引不支持
COMPRESS ADVANCED(报ORA-25193) - 位图索引(
BITMAP INDEX)和索引组织表(IOT)不支持 -
ADVANCED HIGH要求数据库兼容性 ≥12.2.0
压缩效果看 DBA_INDEXES.COMPRESSION 和 LEAF_BLOCKS,但别只盯大小——重复值少的列组合(如主键)启用压缩反而增大索引块数。
最容易被忽略的一点:HCC 压缩块内逻辑数据密度远高于物理块数体现的量,DBA_SEGMENTS.BLOCKS 反映的是压缩后分配的块数,不是原始逻辑块数;用它估算“能存多少行”会严重误判。











