首页 新闻 赞助 找找看

oracle,大数据量插入效率,跪求解决啊!!!!!!!!!!!!!

0
悬赏园豆:5 [待解决问题]

CREATE OR REPLACE PROCEDURE CreateDSJBData(begindate varchar2,enddate varchar2)
AS
cursor cs is SELECT distinct zd FROM xt_ny_dian where zd is not null;
zd varchar2(50);
p_strSql varchar2(32767);
p_index number;
p_tableName varchar2(50);
p_count number;
p_gssj varchar2(20);
p_foreHour varchar2(2);
p_xmbm varchar2(50);
p_zxbm varchar2(50);
p_begindate date;
p_enddate date;
p_exisSql varchar2(1000);
p_strBegindate varchar2(50);
begin
select bm INTO p_xmbm from pt_xm where rownum=1; --项目编码
select bm INTO p_zxbm from xt_ny_zx where rownum=1; --子项编码
p_index:=1;
execute immediate 'alter session enable parallel dml';
for c in cs --游标循环所有点
loop
p_begindate:=to_date(begindate,'yyyy-mm-dd hh24:mi:ss'); --开始时间赋值
p_enddate:=to_date(enddate,'yyyy-mm-dd hh24:mi:ss'); --结束时间赋值
while(p_begindate<=p_enddate) --结束开始时间循环
loop
p_gssj:=to_char(p_begindate,'yyyymmddhh24mi'); --格式化时间
p_tableName:='EC_XS'||to_char(p_begindate,'yyyymmdd'); --分钟表
p_strBegindate:=to_char(p_begindate,'yyyy-mm-dd hh24:mi:ss');
execute immediate 'insert /*+append PARALLEL('||p_tableName||',6)*/ into '||p_tableName||'(ZJ,XH,ZD,CJSJ,HZ,GSSJ)values('''||c.zd||'_'||p_gssj||''','''||to_char(to_number(to_char(p_begindate,'mi'))+1)||''','''||c.zd||''',to_date('''||p_strBegindate||''',''yyyy-mm-dd hh24:mi:ss''),''PT_SF-002'','''||p_gssj||''')';
if(mod(p_index,100000)=0) --取余,以500条插入语句为一批进行执行
then
commit; --提交
--p_strSql:=''; --执行过后,将插入语句清空
end if;
p_index:=p_index+1; --插入语句加1
if(p_foreHour is null or p_foreHour<>to_char(p_begindate,'hh24'))
then
p_tableName:='EC_'||p_xmbm||'_'||p_zxbm||'_XS'||to_char(p_begindate,'yyyymm'); --小时表
p_gssj:=to_char(p_begindate,'yyyymmddhh24');
execute immediate 'insert /*+append PARALLEL('||p_tableName||',6)*/ into '||p_tableName||'(ZJ,XH,ZD,CJSJ,HZ,GSSJ)values('''||c.zd||'_'||p_gssj||''','''||to_char(to_number(to_char(p_begindate,'hh24'))+1)||''','''||c.zd||''',to_date('''||p_strBegindate||''',''yyyy-mm-dd hh24:mi:ss''),''PT_SF-002'','''||p_gssj||''')';
if(mod(p_index,100000)=0)
then
commit; --提交
end if;
p_index:=p_index+1;
end if;
p_foreHour:=to_char(p_begindate,'hh24'); --开始时间的小时
p_begindate:=p_begindate+1/(24*60); --分钟加1
end loop;

p_begindate:=to_date(begindate,'yyyy-mm-dd hh24:mi:ss'); --开始时间赋值
p_enddate:=to_date(enddate,'yyyy-mm-dd hh24:mi:ss'); --结束时间赋值
while(p_begindate<=p_enddate)
loop
p_strBegindate:=to_char(p_begindate,'yyyy-mm-dd hh24:mi:ss');
p_tableName:='EC_'||p_xmbm||'_'||p_zxbm||'_TIAN'||to_char(p_begindate,'yyyy'); --天表
p_gssj:=to_char(p_begindate,'yyyymmdd');
p_exisSql:='select count(1) from '||p_tableName||' where GSSJ='''||p_gssj||''' and zd='''||c.zd||''''; --判断是否存在记录
execute immediate(p_exisSql) into p_count; --判断是否存在记录
if(p_count<1)
then
execute immediate 'insert into '||p_tableName||'(ZJ,XH,ZD,CJSJ,HZ,GSSJ)values('''||c.zd||'_'||p_gssj||''','''||to_char(p_begindate,'dd')||''','''||c.zd||''',to_date('''||p_strBegindate||''',''yyyy-mm-dd hh24:mi:ss''),''PT_SF-002'','''||p_gssj||''')';
end if;
p_begindate:=p_begindate+1; --开始时间天加1
end loop;

--commit;
--初始化开始结束时间
p_begindate:=to_date(begindate,'yyyy-mm-dd hh24:mi:ss'); --开始时间赋值
p_enddate:=to_date(enddate,'yyyy-mm-dd hh24:mi:ss'); --结束时间赋值
--判断当开始时间的月份和结束时间的月份
while(to_number(to_char(p_begindate,'mm'))<=to_number(to_char(p_enddate,'mm')))
loop
p_strBegindate:=to_char(p_begindate,'yyyy-mm-dd hh24:mi:ss');
p_tableName:='EC_'||p_xmbm||'_'||p_zxbm||'_YUE'; --月表
p_gssj:=to_char(p_begindate,'yyyymm');
p_exisSql:='select count(1) from '||p_tableName||' where GSSJ='''||p_gssj||''' and zd='''||c.zd||''''; --判断是否存在记录
execute immediate(p_exisSql) into p_count; --判断是否存在记录
if(p_count<1)
then
execute immediate 'insert into '||p_tableName||'(ZJ,XH,ZD,CJSJ,HZ,GSSJ)values('''||c.zd||'_'||p_gssj||''','''||to_char(p_begindate,'mm')||''','''||c.zd||''',to_date('''||p_strBegindate||''',''yyyy-mm-dd hh24:mi:ss''),''PT_SF-002'','''||p_gssj||''')';
--commit;
end if;
p_begindate:= add_months(p_begindate,1); --开始时间月加1
end loop;


p_tableName:='EC_'||p_xmbm||'_'||p_zxbm||'_NIAN'; --年表
p_gssj:=to_char(p_begindate,'yyyy');
p_strBegindate:=to_char(p_begindate,'yyyy-mm-dd hh24:mi:ss');
p_exisSql:='select count(1) from '||p_tableName||' where GSSJ='''||p_gssj||''' and zd='''||c.zd||''''; --判断是否存在记录
execute immediate(p_exisSql) into p_count; --判断是否存在记录
if(p_count<1)
then
--execute immediate 'insert into '||p_tableName||'(ZJ,XH,ZD,CJSJ,HZ,GSSJ)values('''||c.zd||'_'||p_gssj||''','''||to_char(p_begindate,'yyyy')||''','''||c.zd||''',to_date('''||p_strBegindate||''',''yyyy-mm-dd hh24:mi:ss''),''PT_SF-002'','''||p_gssj||''')';
execute immediate 'insert into '||p_tableName||'(XH,ZD,CJSJ,HZ,GSSJ)values('''||to_char(p_begindate,'yyyy')||''','''||c.zd||''',to_date('''||p_strBegindate||''',''yyyy-mm-dd hh24:mi:ss''),''PT_SF-002'','''||p_gssj||''')';
end if;
end loop;
commit;
end CreateDSJBData;

 

现在自己做测试的时候,只插入一天的数据,游标循环1600次,大概会有250W条数据,需要20分钟才能执行完,,所以请问下该怎么优化。

问题补充:

跪求oracle 高手解决啊。。。。

迷.的主页 迷. | 初学一级 | 园豆:4
提问于:2013-05-22 16:39
< >
分享
所有回答(1)
0

以下是可以考虑优化的:

cursor cs is SELECT distinct zd FROM xt_ny_dian where zd is not null;

循环中对begindate varchar2,enddate varchar2的处理,是可以提取到循环外的

五行缺木 | 园豆:386 (菜鸟二级) | 2013-05-22 17:31

不能放到循环外的啊, ,要不循环下一个游标的时候,p_begindate,p_enddate,是改变后的时间了, ,那肯定出错了。

支持(0) 反对(0) 迷. | 园豆:4 (初学一级) | 2013-05-23 08:52
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册