oracle数据库优化-表碎片优化性能。

在Oracle数据库中,表碎片(Table Fragmentation)通常是由于频繁的DELETEUPDATE操作导致高水位线(HWM, High Water Mark)居高不下,使得数据库在全表扫描时读取了大量包含已删除数据的空块,从而降低查询性能并浪费存储空间。

1 案例:

一次ogg数据库表同步,索引选择性很好,统计表统计信息也不管用,无法进行执行计划绑定,很纳闷,发现表delete很频繁,于是想重新对表进行碎片整理。

对表进行重建后,正常使用索引。

以下是处理Oracle表碎片的主要方式、适用场景及操作步骤:

1. 核心处理方法对比

方法 命令示例 是否在线 是否需要行移动 空间回收效果 适用场景
Shrink Space ALTER TABLE ... SHRINK SPACE 是 (Online) 必须启用 (ROW MOVEMENT) (降低HWM,释放空间给表空间) 大多数堆表,希望在线整理并释放空间
Move Table ALTER TABLE ... MOVE 否 (Offline) 必须启用 (ROW MOVEMENT) (重建表,降低HWM) 维护窗口充足,或无法使用Shrink的旧版本/特殊情况
在线重定义 DBMS_REDEFINITION 是 (Online) 不需要 (内部处理) (重建表) 业务不能中断,且表结构复杂或有依赖对象较多时
导出导入 expdp/impdp 否 (Offline) 不需要 跨平台迁移或极度碎片化需彻底重建时
索引重建 ALTER INDEX ... REBUILD 可选 (ONLINE) N/A N/A (仅针对索引) 配合表整理,必须单独处理索引碎片

2. 推荐方案:ALTER TABLE ... SHRINK SPACE (最常用)

这是Oracle 10g引入的最便捷方式,可以在线压缩数据段,调整高水位线,并释放多余空间回表空间。

前置条件
  • 表所在的表空间必须是 本地管理 (Locally Managed)自动段空间管理 (ASSM)
  • 必须启用行移动功能:因为压缩过程中行的物理位置(RowID)会发生改变。
操作步骤
复制代码
-- 1. 检查并启用行移动 (Row Movement)
ALTER TABLE your_table_name ENABLE ROW MOVEMENT;

-- 2. 执行收缩 (分两步走更稳妥,也可一步到位)
-- 2.1 紧凑数据 (Compact),只整理碎片,不降低高水位线,对业务影响最小
ALTER TABLE your_table_name SHRINK SPACE COMPACT;

-- 2.2 降低高水位线 (Cascade),释放空间给表空间,并级联处理索引
-- 注意:这一步会短暂持有锁,建议在业务低峰期执行
ALTER TABLE your_table_name SHRINK SPACE CASCADE;

-- 3. (可选) 如果之前为了安全开启了行移动,且业务逻辑强依赖RowID不变,可考虑关闭(通常建议保持开启)
-- ALTER TABLE your_table_name DISABLE ROW MOVEMENT; 
  • COMPACT: 仅整理块内碎片,不调整HWM,不释放空间,耗时短,几乎不锁表。
  • CASCADE: 同时整理表及其所有相关索引的碎片。

3. 备选方案:ALTER TABLE ... MOVE

如果表不支持SHRINK(例如非ASSM表空间),或者需要更改表的存储参数(如表空间、PCTFREE等),可以使用MOVE

特点
  • 缺点 :执行期间表不可用(锁表),所有索引会变为 UNUSABLE 状态,必须重建。
  • 优点:彻底重组数据,适用于任何表空间类型。
操作步骤
复制代码
-- 1. 启用行移动
ALTER TABLE your_table_name ENABLE ROW MOVEMENT;

-- 2. 执行移动 (可指定新表空间或存储参数)
ALTER TABLE your_table_name MOVE; 
-- 或者: ALTER TABLE your_table_name MOVE TABLESPACE new_tablespace;

-- 3. 重建索引 (因为MOVE后索引全部失效)
-- 手动重建
ALTER INDEX index_name REBUILD ONLINE;
-- 或者批量重建失效索引
BEGIN
  FOR rec IN (SELECT index_name FROM user_indexes WHERE status = 'UNUSABLE') LOOP
    EXECUTE IMMEDIATE 'ALTER INDEX ' || rec.index_name || ' REBUILD ONLINE';
  END LOOP;
END;
/

4. 高级方案:在线重定义 (DBMS_REDEFINITION)

适用于对可用性要求极高(几乎零停机)、表上有复杂依赖(如触发器、约束、权限)的场景。它通过在后台创建新表、同步数据、切换指针的方式完成。

  • 流程复杂 :需要调用 DBMS_REDEFINITION.START_REDEF_TABLE, SYNC_INTERIM_TABLE, FINISH_REDEF_TABLE 等包。
  • 优势:业务感知度最低,无需手动处理索引和约束(会自动迁移)。

5. 如何判断是否需要整理?

在执行操作前,建议先评估碎片程度。以下SQL可查询表的"浪费空间":

复制代码
SELECT 
    table_name,
    ROUND((blocks * 8 / 1024), 2) AS "高水位线大小 (MB)", -- 假设块大小为8KB
    ROUND((num_rows * avg_row_len / 1024 / 1024), 2) AS "实际数据大小 (MB)",
    ROUND(((blocks * 8) - (num_rows * avg_row_len / 1024)) / 1024, 2) AS "预估浪费空间 (MB)"
FROM user_tables
WHERE table_name = 'YOUR_TABLE_NAME'
AND (blocks * 8) > (num_rows * avg_row_len / 1024) * 1.2; -- 浪费超过20%视为有碎片

注:需确保统计信息是最新的,否则 num_rowsavg_row_len 可能不准。可先执行 EXEC DBMS_STATS.GATHER_TABLE_STATS('USER', 'TABLE_NAME');

也可以使用Oracle自带的 Segment Advisor 进行诊断:

复制代码
-- 创建任务
DECLARE
  tname VARCHAR2(100);
BEGIN
  DBMS_ADVISOR.CREATE_TASK(DBMS_ADVISOR.SQLACCESS_ADVISOR, tname);
  -- 具体参数设置较复杂,通常通过Enterprise Manager (OEM) 图形界面操作更方便
END;
/

6. 重要注意事项

  1. RowID 变化SHRINKMOVE 都会改变行的 ROWID。如果有应用程序硬编码了 ROWID 作为主键或引用,这些程序将失效。
  2. 索引失效
    • SHRINK SPACE CASCADE 会自动维护索引。
    • SHRINK SPACE (不带cascade) 不会更新索引,可能导致索引效率暂时下降,需后续重建。
    • MOVE 会导致所有索引失效,必须重建。
  3. Undo/Redo 压力:碎片整理本质是大量数据的更新和移动,会产生大量的 Undo 和 Redo 日志,务必确保归档空间和Undo表空间充足。
  4. 分区表 :如果是分区表,建议按分区进行整理(ALTER TABLE ... MODIFY PARTITION ... SHRINK SPACE),避免一次性锁住整张大表。
  5. 外键约束 :如果父表进行 MOVESHRINK,子表的外键约束可能会带来额外的锁竞争,需谨慎评估。

总结建议

  • 首选ALTER TABLE ... SHRINK SPACE CASCADE(前提是ASSM表空间且允许Row Movement)。
  • 大表/分区表:按分区逐个执行 Shrink,或在业务低峰期执行。
  • 非ASSM环境 :使用 MOVE + REBUILD INDEX
  • 极致可用性 :使用 DBMS_REDEFINITION
相关推荐
givemeacar2 小时前
Spring Boot中集成MyBatis操作数据库详细教程
数据库·spring boot·mybatis
skiy2 小时前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
IvorySQL2 小时前
PostgreSQL 技术日报 (3月24日)|当 MVCC 成本被重新审视
数据库·postgresql·开源
2401_895521342 小时前
PostgreSQL_安装部署
数据库·postgresql
Hvitur2 小时前
软考架构师【第六章】数据库设计基础知识
数据库·oracle
养生技术人2 小时前
Oracle OCP认证考试题目详解082系列第5题
运维·数据库·sql·oracle·开闭原则
2401_879693872 小时前
使用Python进行图像识别:CNN卷积神经网络实战
jvm·数据库·python
yunyun321232 小时前
机器学习模型部署:将模型转化为Web API
jvm·数据库·python
IvorySQL2 小时前
明晚开播|PostgreSQL 18.3 x IvorySQL 5.3:开启 AI 数据库新纪元
数据库·postgresql·开源