将表数据划分为可管理的块

时间:2018-02-01 07:05:11

标签: sql oracle plsql

考虑Oracle 11g中有81.000行的表:

create  table myTable 
    (
      key1 number not null,
      key2 number not null, 
      key3 number not null,
      col1 varchar2(100),
      col2 varchar2(100),
      col3 varchar2(100)
    );

组合key1, key2, key3是表的主键。

我想将表数据划分为10.000行的块,并将每个块分配给dbms_job.submit以同时对这些行执行某些操作。

这里重要的是不要错过任何记录 - 必须处理所有记录。另外,请记住,键值根本不是连续的。

我想到的一种方法是创建一个临时表

create table mytemp as (select rownum, mytable.* from myTable)

然后使用顺序rownumbers ... 像这样的东西:

for i in 0..(maxChunkNumber-1) loop 
    dbms_job.submit( 'process(i*10000+1,(i+1)*10000)');
end loop;

然而,在上面的选择中添加rownum会大大增加临时表创建所需的时间。

有没有更好的方法来实现这一目标?

欢迎您提出意见。

感谢。

2 个答案:

答案 0 :(得分:1)

使用ORA_HASH并将记录拆分为8个桶。使用DBMS_JOB或DBMS_SCHEDULER处理每个存储桶。

select * from myTable 
where ora_hash(key1 + key2 + key3, 8) = 1; -- bucket 1

select * from myTable 
where ora_hash(key1 + key2 + key3, 8) = 2; -- bucket 2

答案 1 :(得分:0)

首先使用dbms_parallel_execute。 其次是Steward Ashton提出的更好的智能和更快的设计:

Splitting a Table into Rowid Ranges of Equal Size

从不寻常的事情你需要访问dba_extents,但这将是低价格的好解决方案。关键是因为你使用了rowid而不再使用密钥。