如何在ORACLE利用rowid复制数据大表

导语:叶子遇到了一个大表取数的问题,1.9亿的数据量,复制过来的时候使用create table会失败,我们尝试过分日期来提取,开始可以,但等到月末,数据过大,也不能成功获取数据。下面介绍一种利用rowid来分段获取数据的方法。

原理

利用rowid的生成规则,我们可以知道每张表的rowid范围,从而可以利用rowid段来分批获取数据。但由于没有对表dba_extents ,dba_objects赋权,在这里只能用曲线的方式来获取rowid的分段。

获取表的rowid

利用下面的语句获取张表的rowid。注意,下面的语句中的关键字由于知识库系统有限制,所以用空格来拆分了单词。

create table data_936_361808_rid as
select rowid rid from data.data_936_361808@TO_data;

将rowid分组

根据rowid的生成规律,rowid的最后三位是一个块的记录数,我们通过设置记录数最小和最大的值来对块分组。

create table  data_936_361808_ridg as
select   substr(rid,0,15) ridg,count(*) cnt, '0' proc_flog ,substr(rid,0,15)||'AAA' minrid, substr(rid,0,15)||'CcQ' maxrid,0 rnum
   from bsn.data_936_361808_rid
   group by substr(rid,0,15),0;
update data_936_361808_ridg  set rnum =rownum;

取数

上面的准备工作做完后,我们就可以利用下面的过程来取数了。

 DECLARE
  V_SQL VARCHAR2(4000);
BEGIN
  FOR CC IN (SELECT RIDG, PROC_FLOG, MINRID, MAXRID,rnum
               FROM data_936_361808_RIDG
              WHERE PROC_FLOG = 0  AND MOD(rnum, 20) = 0) LOOP
  
    V_SQL := 'insert into  bsn.data_936_361808  select * from data.data_936_361808@to_data  
    where rowid >='''|| CC.MINRID ||''' and rowid<='''|| CC.MAXRID ||''' ';
    EX ECUTE IMMEDIATE V_SQL;
  
    V_SQL := 'update data_936_361808_ridg set proc_flog = ''1'' where ridg = '''|| CC.RIDG ||''' ';
    EX ECUTE IMMEDIATE V_SQL;
  
    CO MMIT;
  END LOOP;
  CO MMIT;
EXCEPTION
  WHEN OTHERS THEN
    ROLLBACK;
END;

另外,我们可以利用MOD来开多个窗口来取数,这样就会很快了,如果开20个窗口,大概一小时能去1200万条数据。

结束

你学会了吗?

发表评论

电子邮件地址不会被公开。 必填项已用*标注