COMPRESS BASIC 仅对直接路径插入生效,不压缩常规DML数据,且UPDATE会导致块解压膨胀;验证需查DBA_TABLES.BLOCKS等物理存储指标,而非仅看COMPRESSION字段。
COMPRESS BASIC 在 Oracle 11g 中**仅对直接路径插入(Direct-Path INSERT)生效**,比如 INSERT /*+ APPEND */ 或 SQL*Loader 的 direct=true 模式。它**不压缩常规 DML(如普通 INSERT、UPDATE、DELETE)产生的数据**,也不在后续修改时触发重压缩。
这意味着:如果你用 INSERT INTO t SELECT ...(无 hint)往一个 COMPRESS BASIC 表里插数据,数据**完全不会被压缩**——块仍是解压形态,空间节省为零。
怎么确认表是否真的被 BASIC 压缩了
不能只看 dba_tables.compression 是 enabled 就认为生效。要验证实际效果,得查物理存储:
- 执行
ANALYZE TABLE t COMPUTE STATISTICS(或DBMS_STATS.GATHER_TABLE_STATS) - 查
DBA_TABLES.BLOCKS和NUM_ROWS,再对比未压缩同结构表的BLOCKS值 - 更准的方法是用
DBMS_SPACE.SPACE_USAGE查段级已用/未用块数
常见误判:表定义写了 COMPRESS,但数据是常规 INSERT 进去的 → BLOCKS 和没压缩一样大。
BASIC 压缩对 DML 的影响很隐蔽
它不拦着你做 UPDATE,但后果是:一旦某行被 UPDATE,Oracle 必须先解压整个数据块(哪怕只改一个字段),再修改、重新写入 —— 这会触发块“膨胀”,甚至导致链式行(chained rows)。后续查询该块时,CPU 要多做一次解压动作,而 I/O 反而可能变差。
-
UPDATE后查V$MYSTAT中table fetch continued row是否上升 - 用
ANALYZE TABLE t LIST CHAINED ROWS抽样检查链式行比例 - 不要在 OLTP 主键更新频繁的表上用
COMPRESS BASIC
什么时候该用 BASIC,而不是 OLTP 压缩
COMPRESS BASIC 只适合「写一次、读多次、几乎不更新」的场景,典型如 ETL 加载后的历史归档表、数据仓库中的事实表快照。
- 加载用
INSERT /*+ APPEND */或sqlldr direct=true - 加载完立刻
ALTER TABLE t NOPARALLEL(避免并行 DML 绕过压缩) - 后续只允许
SELECT,禁用常规UPDATE/DELETE;真要删,用TRUNCATE或DROP PARTITION - 如果业务要求能 UPDATE,必须换
COMPRESS FOR OLTP(需 Advanced Compression 许可)











