确认BasicFile是性能与空间问题主因,需通过MOVE迁移至SecureFile并重建索引,注意COMPRESS/DEDUPLICATE适用场景、手动清理旧段及调整UNDO_RETENTION防ORA-01555。
查 DBA_LOBS 确认是不是 BasicFile 在拖慢查询和撑大空间
lob 查询慢、dba_segments 里看到几百 gb 的 sys_lob% 段,但表本身才几万行——八成是 basicfile 在作祟。直接查:
select table_name, column_name, securefile, in_row, pctversion, chunk from dba_lobs where owner = 'your_schema' and table_name = 'your_table';关键看
securefile 是 no 还是 yes;如果是 no,再盯 in_row = yes 且 pctversion = 10(默认值),这就是双重占用 + 旧版本堆积的典型组合。
ALTER TABLE ... MOVE LOB 是唯一靠谱的升级路径
别信 ALTER TABLE MODIFY LOB (...) STORE AS SECUREFILE 能在线生效——它只对新插入数据起作用,存量数据仍走 BasicFile 路径,空间和性能问题照旧。真正迁移必须用 MOVE:
- 先确认目标表空间是 ASSM:
SELECT segment_space_management FROM dba_tablespaces WHERE tablespace_name = 'TS_LOB_NEW';必须返回AUTO - 执行带 LOB 子句的全表 MOVE:
ALTER TABLE your_schema.your_table MOVE TABLESPACE ts_lob_new LOB (your_lob_col) STORE AS SECUREFILE (COMPRESS HIGH DEDUPLICATE);
- MOVE 后索引失效,必须重建:
ALTER INDEX your_schema.idx_name REBUILD ONLINE;(注意:LOB 索引不支持ONLINE重建,分区表需逐个分区处理) - MOVE 过程锁全表,务必避开业务高峰,并检查
V$SESSION是否有enq: TX - row lock contention
COMPRESS 和 DEDUPLICATE 不是开就省,得看数据特征
这两个参数看着香,但实际效果很“挑人”:
-
COMPRESS HIGH对纯文本、日志、XML 类重复结构有效;对加密后二进制(如 AES 加密 PDF)、JPEG 头部微变的图片,压缩率接近 0 -
DEDUPLICATE是全值哈希比对,两个 10MB 文件只要差 1 字节,就不会去重;高并发 INSERT/UPDATE 时还会卡在全局哈希查找上 - 开启后
DBA_SEGMENTS.BYTES完全不可信——它显示的是分配空间,不是真实占用;必须用DBMS_SPACE.SPACE_USAGE查USED_BYTES才准
迁移后别忘了清理旧段和验证真实空间
MOVE 完成后,原 BasicFile 段不会自动删除,它还躺在表空间里占着位置:
- 手动删前先确认没其他对象依赖:
SELECT owner, segment_name, segment_type FROM dba_segments WHERE segment_name LIKE 'SYS_LOB%_&old_object_id%'; - 删段命令是
DROP SEGMENT(需 DBA 权限),或等 ASSM 自动回收——但前提是没设DELAYED_SEGMENT_CREATION=FALSE - 最易被忽略的是:SecureFiles 的
RETENTION默认基于 undo,如果业务频繁更新 LOB,又没调大UNDO_RETENTION,可能触发ORA-01555,反而让查询更慢

















