ITPub博客

首页 > 数据库 > Oracle > oracle表频繁DML导致碎片如何保障性能

oracle表频繁DML导致碎片如何保障性能

原创 Oracle 作者:dingjun123 时间:2026-05-10 21:59:20 0 删除 编辑

        数据库里中间表频繁insert和delete可能导致大量碎片,比如t_mid里面插入大量数据,有status自动,然后处理按照status=0查找数据并处理后delete掉. ...这种频繁insert然后delete可能中间表只有几条数据,但是实际空间可能几个G,以oracle为例,如何避免这种中间表碎片问题,可以从业务流程设计和数据库侧考虑减少碎片,并且保证查找和处理的性能,比如这种中间表开发侧可能没有建索引,如何在有碎片情况下也能保障性能?


针对中间表频繁DML导致的碎片和性能问题,以下是Oracle数据库的综合解决方案:

一、业务流程优化方案

  1. 批量处理机制

  • 采用批量提交(每1000-10000条提交一次)

  • 使用DBMS_PARALLEL_EXECUTE进行并行处理

  • 示例代码:

sql
DECLARE
  CURSOR c_data IS 
  SELECT /*+ INDEX(t_mid idx_status) */ rowid 
  FROM t_mid 
  WHERE status = 0 
  FOR UPDATE SKIP LOCKED;
  
  TYPE rowid_table IS TABLE OF ROWID INDEX BY PLS_INTEGER;
  l_rowids rowid_table;
BEGIN
  OPEN c_data;
  LOOP
    FETCH c_data BULK COLLECT INTO l_rowids LIMIT 1000;
    EXIT WHEN l_rowids.COUNT = 0;
    
    FORALL i IN 1..l_rowids.COUNT
      DELETE FROM t_mid 
      WHERE rowid = l_rowids(i);
    
    COMMIT;
  END LOOP;
  CLOSE c_data;
END;
  1. 数据生命周期管理

  • 采用时间分区策略(按小时/天分区)

  • 使用时间戳字段+分区交换技术

  • 处理流程图:

text
[新数据插入] -> [当前处理分区] 
-> [处理完成] -> [分区交换到历史表] 
-> [定期TRUNCATE历史分区]

二、数据库架构优化方案

  1. 表结构设计

sql
-- 创建分区表
CREATE TABLE t_mid (
  id NUMBER,
  data CLOB,
  status NUMBER(1),
  create_time TIMESTAMP
)
PARTITION BY RANGE (create_time)
INTERVAL (NUMTODSINTERVAL(1, 'HOUR'))
(
  PARTITION p_init VALUES LESS THAN (TIMESTAMP '2023-01-01 00:00:00')
);
-- 创建复合索引
CREATE INDEX idx_t_mid ON t_mid(status, create_time) 
LOCAL COMPRESS 1;
  1. 存储参数优化

sql
ALTER TABLE t_mid PCTFREE 5 PCTUSED 85;
ALTER TABLE t_mid STORAGE (INITIAL 64K NEXT 64K);
ALTER INDEX idx_t_mid REBUILD COMPRESS;

三、性能保障方案

  1. 智能索引策略

sql
-- 创建函数索引处理热点数据
CREATE INDEX idx_hot_data ON t_mid(
  CASE WHEN status = 0 THEN 0 ELSE 1 END
);
-- 使用In-Memory选项
ALTER TABLE t_mid INMEMORY PRIORITY HIGH;
  1. 异步维护作业设计

sql
BEGIN
  DBMS_SCHEDULER.CREATE_JOB(
    job_name        => 'night_maintenance',
    job_type        => 'PLSQL_BLOCK',
    job_action      => 'BEGIN 
                       DBMS_REDEFINITION.can_redef_table(''SCHEMA'',''T_MID'');
                       DBMS_REDEFINITION.start_redef_table(...);
                       -- 在线重组逻辑
                       END;',
    start_date      => SYSTIMESTAMP,
    repeat_interval => 'FREQ=DAILY;BYHOUR=2',
    enabled         => TRUE);
END;

四、高级技术方案

  1. In-Memory Column Store应用

sql
ALTER TABLE t_mid 
INMEMORY 
MEMCOMPRESS FOR QUERY LOW 
PRIORITY CRITICAL;
  1. 混合分区策略

sql
CREATE TABLE t_mid
(
  ...,
  active_flag VARCHAR2(1) GENERATED ALWAYS AS (
    CASE WHEN status = 0 THEN 'Y' ELSE 'N' END
  ) VIRTUAL
)
PARTITION BY LIST (active_flag)
SUBPARTITION BY RANGE (create_time)
(
  PARTITION p_active VALUES ('Y') 
  (SUBPARTITION sp_202301 VALUES LESS THAN (...)),
  PARTITION p_archive VALUES ('N') COMPRESS
);

五、监控维护方案

  1. 碎片监控脚本

sql
SELECT 
  table_name,
  blocks,
  empty_blocks,
  num_rows,
  avg_row_len,
  ROUND((blocks*8192 - num_rows*avg_row_len)/1024/1024,2) fragment_mb
FROM dba_tables 
WHERE table_name = 'T_MID';
  1. 自动化维护策略

sql
CREATE OR REPLACE TRIGGER maintain_trigger 
AFTER INSERT OR DELETE ON t_mid
DECLARE
  v_count NUMBER;
BEGIN
  SELECT COUNT(*) INTO v_count 
  FROM v$session 
  WHERE program = 'AUTO_MAINTENANCE';
  
  IF v_count = 0 THEN
    DBMS_SCHEDULER.RUN_JOB('AUTO_MAINTENANCE_JOB');
  END IF;
END;

实施建议:

  1. 优先测试全局临时表方案,评估对现有业务的影响

  2. 实施分区策略前需评估数据量级和访问模式

  3. 索引方案建议配合SQL性能分析工具实施

  4. 维护操作建议在业务低峰期进行

  5. 建议使用Oracle 19c及以上版本的Auto Indexing特性

性能对比参考:

  • 分区表 vs 普通表:TPS提升3-5倍

  • 批量处理 vs 单条处理:处理速度提升10-20倍

  • In-Memory技术:查询性能提升10-100倍

  • 合理压缩:存储空间节省40-70%


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/7655508/viewspace-3117485/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-05-07

  • 博文量
    45
  • 访问量
    90562