ORACLE存储过程执行很慢!

mynada 2010-10-30 05:37:55
里面使用了游标,4000行的数据也要执行5-10分钟,如果10000多行我等半个小时都执行不完·大家看看我的语句是不是有问题啊?插入的表里没有触发器,且是在我本地的数据库执行,我新手大家帮帮忙
------------------------------------------------------------------
CREATE OR REPLACE PROCEDURE proc_InitializeStock is
BEGIN
DECLARE
CURSOR c_Initialize IS
select ins_partcode,
ins_partdesc,
ins_partformat,
ins_partuom,
ins_cz,
ins_th,
ins_partlstore,
ins_parthstore,
ins_stoqty,
ins_price,
ins_planprice,
ins_store,
ins_bin,
ins_zy,
ins_xt,
ins_zsb,
ins_yt,
ins_isins
from sys_initializestock
WHERE ins_isins = '0';

partCout number; --备件记录数
tranCode o_Transactions.Tra_Code%type; --交易编号
binTemp number; --货位是否存在
iniStore sys_initializestock%rowtype; --单条数据

BEGIN
--业务主表记录
SELECT O_TRANS.NEXTVAL INTO tranCode FROM DUAL;
insert into o_transactions
(tra_code, tra_desc, tra_type, tra_user)
values
(tranCode, '库存初始', 'R', 'admin');

--开始游标
OPEN c_Initialize;
LOOP
FETCH c_Initialize
INTO iniStore;
EXIT WHEN c_Initialize%NOTFOUND;
--处理物资编码
SELECT count(*)
INTO partCout
FROM p_Parts
WHERE Par_Code = trim(iniStore.Ins_Partcode);
IF (partCout = 0) THEN
insert into p_parts
(par_code,
par_desc,
par_format,
par_uom,
par_cz,
par_th,
par_lstore,
par_hstore,
par_createduser)
values
(trim(iniStore.ins_partcode),
iniStore.ins_partdesc,
iniStore.ins_partformat,
iniStore.ins_partuom,
iniStore.ins_cz,
iniStore.ins_th,
iniStore.ins_partlstore,
iniStore.ins_parthstore,
'admin');
END IF;
--货位处理
SELECT count(Bin_Code)
INTO binTemp
FROM s_Bins
WHERE bin_Code = trim(iniStore.ins_bin)
AND bin_store = storecode_storename(iniStore.ins_store);
IF (binTemp = 0) then
insert into s_bins
(bin_store, bin_code)
values
(storecode_storename(iniStore.ins_store), trim(iniStore.ins_bin));
end if;
--处理业务
insert into o_translines
(trl_trans,
trl_type,
trl_part,
trl_store,
trl_bin,
trl_lot,
trl_price,
trl_qty,
trl_filiale,
trl_zy,
trl_xt,
trl_zsb,
trl_yt,
trl_planprice,
TRL_USER,
trl_date)
values
(tranCode,
'R',
trim(iniStore.ins_partcode),
storecode_storename(iniStore.ins_store),
trim(iniStore.ins_bin),
'20091125001',
iniStore.ins_price,
iniStore.ins_stoqty,
filialecode_storecode(storecode_storename(iniStore.ins_store)),
iniStore.ins_zy,
iniStore.ins_xt,
iniStore.ins_zsb,
iniStore.ins_yt,
iniStore.ins_planprice,
'admin',
to_date('2010-1-31','yyyy-mm-dd'));

--修改初始后状态
UPDATE sys_initializestock
set ins_isins = '1'
where ins_partcode = iniStore.ins_partcode;
END LOOP;
CLOSE c_Initialize;
END;
END proc_InitializeStock;
...全文
1051 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
zkl516321905 2010-11-01
  • 打赏
  • 举报
回复
代码太多,简单的看了一下,推荐楼主可以做个试验,你先是查询数据,然后在插入数据,楼主可以测试一下,先从那个表查询看要多少时间,然后再通过你写的代码插入又需要多少时间,看哪个环节比较慢,就能知道是游标的问题还是loop的问题了。
香波儿 2010-10-31
  • 打赏
  • 举报
回复
如果使用游标循环,可以批量插入,例如:每100条插入一次,这样就可以减少回滚段:
势力:

for i in 1..100 loop
insert /*+append*/ into t .....;
if (mod(i,100)=0) then --每100条commit一次
commit;
end if ;
end loop;
commit;
palm_civet 2010-10-31
  • 打赏
  • 举报
回复
先看看是sql慢还是plsql的程序慢,程序慢的话不要用游标,用forall,sql慢的话看看能不能优化sql
cowboyhn 2010-10-30
  • 打赏
  • 举报
回复
你的处理逻辑是先判断表p_Parts、s_Bins没有相应记录,然后再从sys_initializestock表取数据插入,
如果表p_Parts、s_Bins数据较多,且没用用到索引,则每次查询记录数会很慢,建议不用循环,改成如下
单条语句,另外需确认表p_Parts的Par_Code是否有索引

insert into p_parts
(par_code,
par_desc,
par_format,
par_uom,
par_cz,
par_th,
par_lstore,
par_hstore,
par_createduser)
select
trim(ins_partcode),
ins_partdesc,
ins_partformat,
ins_partuom,
ins_cz,
ins_th,
ins_partlstore,
ins_parthstore,
'admin'
from sys_initializestock A
WHERE ins_isins = '0'
AND NOT EXISTS (SELECT 1 FROM p_Parts
WHERE Par_Code = trim(A.Ins_Partcode))
mynada 2010-10-30
  • 打赏
  • 举报
回复
最后的确修改了initializestock整个表了,你看看哪里可以优化呢?
gelyon 2010-10-30
  • 打赏
  • 举报
回复
是不是你又查询又修改sys_initializestock表的原因,再有就是你DML语句多了产生的回滚段就多,造成慢也是理所当然的。根据你具体业务逻辑来看,是否有必要进行批量提交,及时释放回滚段,看你业务逻辑了这要。

17,377

社区成员

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

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