导语:叶子遇到了一个大表取数的问题,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万条数据。
结束
你学会了吗?