大数据量的两个表数据复制的一些经验总结

论坛 期权论坛 脚本     
匿名技术用户   2020-12-30 08:25   34   0

1.如果两个表的数据结构一样,可以考虑很多种方式:

(1)create table as select * from tbl_name;

(2) insert /*+ append*/ into tbl_name select * from tbl_name,如果软件平台与硬件平台够好,可以考虑加入parallel的hits。

(3)引入脚本:

DECLARE
maxnum number defult 5000;
CURSOR cur IS
SELECT * FROM aa;--定义游标
TYPE rec IS TABLE OF aa%ROWTYPE;--定义类型
recs rec;
BEGIN
OPEN cur; --打开游标

LOOP --循环条件

EXIT WHEN cur%NOTFOUND;--游标结束条件
FETCH cur BULK COLLECT --取游标里的值
INTO recs LIMIT maxnum; --提交条件,每5000条提交
FORALL i IN 1 .. recs.COUNT --这个是个计数器,用来确保提交的条数,也是循环
INSERT INTO bb VALUES recs (i);--插入目标表
COMMIT; --提交
END LOOP; --停止循环
CLOSE cur;--关闭游标1,

END;

这种方式适用于要两个表结构一样的情况。


2.两个表结构不一样,方法也是类似的:

(1)insert /*+ append*/ into tbl_name(col1,col2,....) select col1,col2,... from tbl_name,如果软件平台与硬件平台够好,同样可以考虑加入parallel的hits。如果对select语句进行列值处理,比如函数,性能影响很大。


3.复制千万级数据表时用的存储过程

CREATE OR REPLACE PROCEDURE "LARGEDATA_INSERT" (ip_table_name in varchar2, --目标表
ip_table_column in varchar2, --目标字段
ip_table_select in varchar2, --SELECT 查询语句
return_result out number --返回的结果1,表示成功,0表示失败
) as
--适合大数据量的插入模板 create Templates by chenzhoumin 20110614
runTime number;--运行总次数
i number;--当前行数
amount number;--总行数
s_sql varchar2(10000);--SQL语句
e_sql varchar2(10000);--执行SQL语句
countNumber number;--一次插入的数据量
begin
--set serveroutput on size 20000000000000
countNumber := 10000;
return_result := 0; --开始初始化为0
--核必逻辑内容,可根据具体的业务逻辑来定义,统计数据总行数
s_sql := 'select count(1) from (' || ip_table_select || ')';
execute immediate s_sql
into amount;
--每100万提交一次
runTime := amount mod countNumber;
if (runTime > 0) then
runTime := 1 + trunc(amount / countNumber);
end if;
if (runTime = 0) then
runTime := 0 + trunc(amount / countNumber);
end if;
FOR i IN 1 .. runTime LOOP
e_sql := 'insert into '||ip_table_name ||'
('||ip_table_column ||')
select '|| ip_table_column ||'
from
(select selectSec.*, rownum rownumType
from ('|| ip_table_select ||') selectSec
WHERE ROWNUM <= '|| i * countNumber ||')
WHERE rownumType > '||(i - 1) * countNumber;
dbms_output.enable(99999999999999);
dbms_output.put_line(e_sql);
execute immediate e_sql;
--提交
commit;
END LOOP;
return_result := 1;
return;
exception
when others then
return_result := 0;
raise;
dbms_output.enable(99999999999999);
dbms_output.put_line('结束');
return;
end;
其实这个存储过程当查询到数据千万以后也是挺慢的。


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP