各位大侠,
我有一个Oracle中SQL语句的效率问题,问题描述如下:
当前库:A 备份库:B
在A库上执行如下语句:
EXEC SQL insert into table1_bak select * from table1 where date <= :date;
EXEC SQL delete from table1 where date <= :date;
其中:table1是A库中的表,有5万条当日的流水记录;
table1_bak是B库的表,通过DB Link的同义词映射到A库上,保存着所有的流水记录,表大小为15G,估计有几千万条记录。 该语句的目的就是\把当天的流水记录备份到历史记录中,然后清表。 这样的两条语句执行下来需要大约20分钟,太慢了。 这种类似的操作很多,一个完整的批处理流程走下来需要2个小时。 哪位专家有优化的方法?可以优化上述的语句或优化表?
我有一个Oracle中SQL语句的效率问题,问题描述如下:
当前库:A 备份库:B
在A库上执行如下语句:
EXEC SQL insert into table1_bak select * from table1 where date <= :date;
EXEC SQL delete from table1 where date <= :date;
其中:table1是A库中的表,有5万条当日的流水记录;
table1_bak是B库的表,通过DB Link的同义词映射到A库上,保存着所有的流水记录,表大小为15G,估计有几千万条记录。 该语句的目的就是\把当天的流水记录备份到历史记录中,然后清表。 这样的两条语句执行下来需要大约20分钟,太慢了。 这种类似的操作很多,一个完整的批处理流程走下来需要2个小时。 哪位专家有优化的方法?可以优化上述的语句或优化表?
再就是楼上所说的,用truncate删除(提醒一下,truncate删除不能回退)
1)插入的主要性能瓶颈我觉得可能在网络速度(因为采取db link的方式)以及备份表存在索引、约束。在这样的环境中,备份表的索引、约束都应该被禁用。另外采用insert /*+append*/ into ...的方式会提高插入效率(减少空间计算)
2)删除应该花费不了多少时间(如果不需要回滚、日志等,可以采用truncate的方式,但对整体性能提升应该不大),主要性能花费应该是在insert上。
3)前面几位说的采用分区表的方式我不太认同。按照楼主所说是每天都把流水记录转到备份表中去,就是说当前表基本上只存储当天的纪录,那么按日期分区就没什么意义。备份表分区还差不多,但备份表不用来查询。
再分析一下sql是不是能有效的利用到索引,每次执行这个SQL前最好重新分析一下这个table 的索引