请教:关于大量数据插入性能的问题!

「已注销」 2007-04-25 10:27:32
我的程序每天要读取200万至2000万条记录入库,入库的时间是由程序收到数据后决定的,程序收到的数据存在一个buf里,我需要把它解释出来入库,一般来说解释出来一个buf里估计含200条记录,我现在的做法是:
我在数据库中建立一个存储过程:ProIns,每次插入一条记录,同时记录是有主键的,如果存在相同的纪录,则不插入,过程如下:

create or replace procedure ProIns (T_ID in varchar2,
P_D in varchar2)

as
RecordNum Number;

begin
select count(*) into RecordNum from table1 where TID = T_ID;
if RecordNum=0 then

insert into table1 (TID,PD) values (T_ID,P_D);

commit;

end if;

exception when others then
null;

end ProIns;
/
然后我在程序中循环调用该存储过程,每次插入一条记录,这样就很慢,怎么样
提高入库性能呢?

大概有以下几个特点:
1、无法保证入库的数据的唯一性;
2、数据入库时间不定;
3、一次接收到的buf中包含的纪录数不定;
4、表有关键字:t_id;
5、其他人可以在任意时候查询该表;

象这种情况,怎样提高入库性能?谢谢
...全文
433 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
Hero__008 2007-05-20
  • 打赏
  • 举报
回复
lz包子兄的做法是可行的~
「已注销」 2007-05-20
  • 打赏
  • 举报
回复
up
「已注销」 2007-05-08
  • 打赏
  • 举报
回复
v$session_wait

很可能出现buffer busy waits

这是什么意思呢?
liuyi8903 2007-05-06
  • 打赏
  • 举报
回复
v$session_wait

很可能出现buffer busy waits
「已注销」 2007-05-06
  • 打赏
  • 举报
回复
To
jdsnhan(柳荫凉) ( ) 信誉:100 Blog 加为好友 2007-5-1 10:56:39 得分: 0



select count(*) into RecordNum from table1 where TID = T_ID;
if RecordNum=0 then
insert into table1 (TID,PD) values (T_ID,P_D);
用这样的方法,造成频繁的访问,肯定要慢啊。
把连接的方法降低,速度肯定会变快的。


把连接的方法降低,速度肯定会变快的。 怎么降低呢?

jdsnhan 2007-05-01
  • 打赏
  • 举报
回复
select count(*) into RecordNum from table1 where TID = T_ID;
if RecordNum=0 then
insert into table1 (TID,PD) values (T_ID,P_D);
用这样的方法,造成频繁的访问,肯定要慢啊。
把连接的方法降低,速度肯定会变快的。
chufeng_007 2007-04-30
  • 打赏
  • 举报
回复
楼上:baojianjun(包子)做法最好,肯定可行,效率也高,不过可以改进的是,在每次插入完成后就删除临时表(或表类型和你的 table1 结构一致的表)的数据,因为有大量的数据时,select count(*)会很费时间,每次都调存储过程更费时间,包子做法可以批量插入,性能肯定能大大提高.
「已注销」 2007-04-30
  • 打赏
  • 举报
回复
我用forall性能提高不少,但是现在有个问题:用forall可以用于更新吗?好像不行:如果我要大量的更新表的某个字段,怎么办呢?

谢谢
「已注销」 2007-04-29
  • 打赏
  • 举报
回复
楼上的怎么弄得呢?
yj1804 2007-04-27
  • 打赏
  • 举报
回复
在我的机器配置上,使用direct-path和不使用的插入速度差距在5倍左右,现在一秒钟可以插入80000多条了(无索引)
yj1804 2007-04-27
  • 打赏
  • 举报
回复
我刚刚也在弄类似的问题。
有索引的时候插入速度会明显下降,如果对日志要求不高可以使用direct-path插入,这样就不会写redo日志,可以极大的提升插入性能。
doer_ljy 2007-04-27
  • 打赏
  • 举报
回复
icedut(冰-装修准备中) 说得很对阿。
同时个人认为,效率低下主要还是调用Procedure过于频繁。
LZ可以考虑积累1~10万条,执行一次插入数据库操作。
另外,为了能够有效的减少select count(*)的次数,可以按照表的主键使用hash结构,保证准备插入数据库中的数据本身主键不会重复。
icedut 2007-04-26
  • 打赏
  • 举报
回复
插入200万至2000万

日志也会很大啊
不知道lz想怎么处理
baojianjun 2007-04-26
  • 打赏
  • 举报
回复
1.先建立一张临时表table_temp或者一个表类型和你的 table1 结构一致,在table_temp与TABLE1相同的主键栏位上建索引,
2.将你解析的数据(buffer里的)一次全部插入这个临时表table_temp
3.存储过程中改为
begin
insert into table1 (TID,PD)
select a.TID,a.PD from table_temp a
where not exists (select 'x' from
table1 b where a.TID = b.TID)
commit;
end;
/
以上只是个人想法没有经过测试,可遇见的是可以大量减少对于table1的INSERT操作
CathySun118 2007-04-26
  • 打赏
  • 举报
回复
用表类型,数组类型应该都可以
「已注销」 2007-04-26
  • 打赏
  • 举报
回复
怎么改呢?存储过程可以以数组作为参数吗?
CathySun118 2007-04-25
  • 打赏
  • 举报
回复
更改存储过程,一次传人多条记录的条件,批量提交

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧