如何优化循环

时间:2019-05-13 05:40:43

标签: database oracle for-loop optimization plsql

我需要优化PLSQL函数中使用的for循环。该功能用于制作报告,但是花费的时间太长(大约1小时)。这是代码:

select c.id id_constr, s.id id_side, 
       coalesce(datumz, tz_date(2099, 12).datum) datum_z
  BULK COLLECT INTO arr_idConstruction, arr_idSide, arr_datumZ  
  from sp_constructions c, sp_constr_sides s
 where c.id = s.id_construction
 order by c.nummer, s.id;

for n_month in 1..12 loop

    nArbeit := 0;
    nTRS    := 0;
    nTSJ    := 0;
    nLight  := 0;
    dDate  := tz_date(pnYear, n_month).datum;

    FOR idx IN 1 .. arr_idConstruction.COUNT LOOP

      select coalesce(sum(kost_beim_bit), 0)
        into nArbeit_
        from table(dd_side_arbeit.f(arr_idSide(idx))) a
       where a.aktiv = 1
         and a.datum between tz_date(pnYear, n_month).d01 and last_day(tz_date(pnYear, n_month).d01);

      nArbeit := nArbeit + nArbeit_;

      nTRS := nTRS + dd_bewerbung.f_trs_anrechnen(
                                                 arr_idSide(idx),
                                                 dDate,
                                                 add_months(dDate, 1)-1
                                                 );

      if ( dDate <= arr_datumZ(idx) ) then

          begin

            select tsj, light
              into nTSJ_, nLight_
              from (select tsj, light
                      from t_constr_side_expenses s
                     where dDate >= s.datum
                       and s.id_side = arr_idSide(idx)
                     order by datum desc)
             where rownum = 1;

            nTSJ   := nTSJ   + nvl(nTSJ_,   0);
            nLight := nLight + nvl(nLight_, 0);

          exception
            when others then null;
          end;

      end if;

    end loop;

    select sum(b.betrag)
      into nBez
      from t_vertrag_bezahlung b
     where b.datum between dDate and
           add_months(dDate, 1) - 1;

    ttnArbeit.extend; ttnArbeit(ttnArbeit.count) := nArbeit;
    ttnTRS.extend;    ttnTRS(ttnTRS.count)       := nTRS;
    ttnTSJ.extend;    ttnTSJ(ttnTSJ.count)       := nTSJ;
    ttnLight.extend;  ttnLight(ttnLight.count)   := nLight;
    ttnENP.extend;    ttnENP(ttnENP.count)       := round(nArbeit*nENP_prz);
    ttnBez.extend;    ttnBez(ttnBez.count)       := nBez;

    tpMX.extend;
    tpMX( tpMX.count ) := tt_varchar2(  d2c( dDate ),
                                        nArbeit,
                                        nTRS,
                                        nTSJ,
                                        nLight,
                                        round(nArbeit*nENP_prz),
                                        nBez
                                      );

  end loop;

arr_idConstruction 集合大约有1000条记录,每年的每个月都需要进行一些计算。因此,此代码大约执行了12000次(12个月x 1000记录)。 有什么方法可以优化此代码?

0 个答案:

没有答案