0

Quantity(ユーザー、年、数量) と MonthlyQuantity(ユーザー、年、月、数量) の 2 つのテーブルがあります。毎月のテーブルは空です。私がする必要があるのは、年間数量を 12 等分し、最後の月に残りを追加することによって、年間数量に基づいて月次表を埋めることです。したがって、基本的に、Quantity の各行は QuantityMonthly に 12 行を作成する必要があります。これが私が行う方法です-問題は、ループが非常に遅いことです。

どうすればもっと速くできますか?

    create ro replace 
procedure pr_test
AS
BEGIN
    FOR r IN (SELECT * FROM Quantity) LOOP

    DELETE FROM QuantityMonthly qm WHERE qm.company = r.company AND qm.year = r.year;

    INSERT ALL
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 1, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 2, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 3, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 4, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 5, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 6, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 7, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 8, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 9, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 10, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 11, trunc(r.quantity / 12))
    INTO QuantityMonthly (company, year, mon, qty) values (r.company, r.year, 12, trunc(r.quantity / 12) + mod(r.quantity , 12))
  SELECT * FROM dual;

END LOOP;

COMMIT;

END pr_test;
4

1 に答える 1

1

単一のステートメントを使用します。多くの場合、単一の集合操作は多くの小さな操作よりもはるかに高速です。

MERGE INTO QuantityMonthly qm
 USING (SELECT *
          FROM Quantity q
         CROSS JOIN (SELECT rownum mon
                       FROM dual
                    CONNECT BY level <= 12)) q
    ON (qm.company = q.company
        AND qm.year = q.year
        AND qm.mon = q.mon)
WHEN MATCHED THEN
   UPDATE SET qm.quantity = q.quantity / 12 
                            + CASE WHEN q.mon = 12 THEN 
                                 mod(r.quantity, 12) 
                              ELSE 
                                 0 
                              END
WHEN NOT MATCHED THEN
   INSERT (company, year, mon, qty)
   VALUES (q.company, q.year, q.mon,
           q.quantity / 12 
           + CASE WHEN q.mon = 12 THEN mod(r.quantity, 12) ELSE 0 END);
于 2012-09-27T12:14:08.547 に答える