DBMS_LOB函数无法压缩LOB,压缩必须在表定义时通过SECUREFILE+COMPRESS属性启用;COMPRESS BASIC仅对直接路径插入生效,COMPRESS FOR OLTP对所有DML生效但依赖块级阈值触发,二者均不压缩CLOB/BLOB内容。
dbms_lob 函数不能压缩 lob 数据,表压缩也不能在 pl/sql 运行时“调用”实现——所有压缩行为都由存储层定义驱动,不是过程式逻辑。
COMPRESS FOR OLTP 和 COMPRESS BASIC 的区别在哪
二者压缩触发时机和适用场景完全不同,混用会导致预期外的空转或失败:
-
COMPRESS BASIC只在直接路径插入(如INSERT /*+ APPEND */)时生效,普通INSERT或UPDATE不压缩,适合只读/低频更新的数据仓库表 -
COMPRESS FOR OLTP对任何 DML 都生效,但压缩不是实时逐行发生,而是当块内“未压缩行数达到阈值”后,后台自动对整块重组织并压缩,适合高并发事务表 - 两者都不支持
CLOB/BLOB列内容压缩——LOB 压缩必须走SECUREFILE + COMPRESS表定义路径,和行压缩无关 -
COMPRESS FOR OLTP在 11gR2+ 才真正可用;低于该版本即使语法通过,实际不生效
ALTER TABLE ... COMPRESS 为什么锁表这么久
直接执行 ALTER TABLE t ENABLE COMPRESSION 或 MOVE PARTITION p1 COMPRESS FOR OLTP 会触发物理重写:Oracle 必须读取所有数据块、重组、压缩、再写回。大表可能持续数小时,且全程 DML 阻塞。
- 分区表优先用
ALTER TABLE t MOVE PARTITION p1 COMPRESS FOR OLTP ONLINE(12cR2+),ONLINE关键字可避免 DML 阻塞,但仍有短暂 DDL 排他锁 - 非分区表或旧版本,改用
DBMS_REDEFINITION在线重定义:先建压缩版空表 → 同步数据 → 原子切换,业务零中断但步骤多 - 别信“加
PCTFREE 0就能加速压缩”——压缩效率取决于重复模式,和空闲空间无关;反而PCTFREE设太小会导致后续UPDATE频繁迁移行
SECUREFILE LOB 压缩必须在建表时定死
已存在的 BASICFILE LOB 列无法直接升级为压缩型 SECUREFILE,也没有“给已有 LOB 补压缩”的在线命令。
- 必须重建:用
DBMS_REDEFINITION或导出/重建/导入;ALTER TABLE ... MODIFY LOB(col) (STORE AS SECUREFILE COMPRESS HIGH)仅对新建列有效,对存量数据无效 - 分两步启用更安全:
MODIFY LOB(col) (STORE AS SECUREFILE)(秒级,只改字典)→ 再MODIFY LOB(col) (COMPRESS HIGH)(耗时,真正扫描压缩) -
COMPRESS HIGH比MEDIUM多压 10–15% 空间,但 CPU 解压开销翻倍,OLTP 场景下读取延迟涨 3–5 倍,别盲目选 HIGH -
DEDUPLICATE不是“文件去重”,只对同一列中完全相同的原始二进制值生效;编码差异(如UTL_RAW.CAST_TO_RAWvsUTL_I18N.STRING_TO_RAW)会导致哈希不匹配,照样存两份
真正决定压缩是否生效的,从来不是 PL/SQL 里写了什么函数,而是建表语句里的 COMPRESS、STORE AS SECUREFILE、分区 MOVE 时的参数,以及你有没有给 Oracle 留出足够资源去完成物理重写。压缩后的读性能下降是设计使然,不是配置错了。


















