里面使用了游标,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;

解决方案 »

  1.   

    是不是你又查询又修改sys_initializestock表的原因,再有就是你DML语句多了产生的回滚段就多,造成慢也是理所当然的。根据你具体业务逻辑来看,是否有必要进行批量提交,及时释放回滚段,看你业务逻辑了这要。
      

  2.   

    最后的确修改了initializestock整个表了,你看看哪里可以优化呢?
      

  3.   

    你的处理逻辑是先判断表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))
      
      

  4.   

    先看看是sql慢还是plsql的程序慢,程序慢的话不要用游标,用forall,sql慢的话看看能不能优化sql
      

  5.   

    如果使用游标循环,可以批量插入,例如:每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;
      

  6.   

    代码太多,简单的看了一下,推荐楼主可以做个试验,你先是查询数据,然后在插入数据,楼主可以测试一下,先从那个表查询看要多少时间,然后再通过你写的代码插入又需要多少时间,看哪个环节比较慢,就能知道是游标的问题还是loop的问题了。