2017-12-28 33 views
0

** 100,000行を高速にロードする方法。複数の挿入の代わりに1つの挿入が必要です**私は複数のOracleテーブルからデータを取るスクリプトを持っています。指図タイプに基づいて、一時テーブルへの複数の挿入があります。注文タイプに基づいて10万レコード以上のレコードが挿入されます。注文タイプに基づく複数の挿入は12-14分かかります。より速い方法?オラクル表への複数の挿入を避ける

   prompt Querying freight ... 
      SET serveroutput ON SIZE 1000000 
      DECLARE 

       CURSOR c_progpcon 
       IS 
        SELECT cust_id 
         ,div_no 
        FROM dss.program_processing_controls; 

       CURSOR c_custord(in_orgrole_id_customer IN dss.orders.orgrole_id_customer%TYPE) 
       IS 
        SELECT id order_id 
         ,order_type 
         ,order_number 
         ,customer_po 
        FROM dss.orders 
        WHERE order_type = 'CUST' 
         AND orgrole_id_customer = in_orgrole_id_customer; 

       CURSOR c_outbound(in_order_id IN dss.orders.id%TYPE) 
       IS 
        SELECT ship.id ship_id 
         ,ship.shipper_no 
         ,shptrk.id shptrk_id 
         ,shptrk.waybill 
         ,shptrk.estimated_freight 
         ,shptrk.actual_freight 
         ,shptrk.dt_created 
        FROM dss.shipments ship 
         ,dss.shipment_trackings shptrk 
        WHERE ship.order_id = in_order_id 
         AND shptrk.ship_id = ship.id 
        -- and ship.id = 2290451 
         AND shptrk.dt_created BETWEEN TO_DATE('01-JAN-2017','dd-MON-yyyy') 
                AND TO_DATE('31-DEC-2017','dd-MON-yyyy'); 

       CURSOR c_ordsch(in_order_id IN dss.orders.id%TYPE) 
       IS 
        SELECT ordsch.id ordsch_id 
        FROM dss.orders ord 
         ,dss.ordered_items orditm 
         ,dss.ordered_item_schedules ordsch 
        WHERE ord.id = in_order_id 
         AND orditm.order_id = ord.id 
         AND ordsch.orditm_id = orditm.id; 

       CURSOR c_inbound(in_orditm_id IN dss.ordered_items.id%TYPE) 
       IS 
        SELECT recshp.id recshp_id 
         ,recshp.waybill 
         ,recshp.estimated_freight 
         ,recshp.actual_freight 
         ,recshp.dt_created 
        FROM dss.built_items bltitm 
         ,dss.received_shipments recshp 
        WHERE bltitm.orditm_id_rcvd = in_orditm_id 
         AND recshp.id = bltitm.recshp_id 
         AND recshp.dt_created BETWEEN TO_DATE('01-JAN-2017','dd-MON-yyyy') 
                AND TO_DATE('31-DEC-2017','dd-MON-yyyy') 
        UNION ALL 
        SELECT recshp.id recshp_id 
         ,recshp.waybill 
         ,recshp.estimated_freight 
         ,recshp.actual_freight 
         ,recshp.dt_created 
        FROM dss.received_items rcvitm 
         ,dss.received_shipments recshp 
        WHERE rcvitm.orditm_id_rcvd = in_orditm_id 
         AND recshp.id = rcvitm.recshp_id 
         AND recshp.dt_created BETWEEN TO_DATE('01-JAN-2017','dd-MON-yyyy') 
                AND TO_DATE('31-DEC-2017','dd-MON-yyyy'); 

       v_cust_processed NUMBER := 0; 
       v_custord_processed NUMBER := 0; 
       v_orgrole_id_customer dss.org_roles.id%TYPE; 

       v_estimated_freight_custord adwaram.order_freight.estimated_freight%TYPE; 
       v_actual_freight_custord adwaram.order_freight.actual_freight%TYPE; 

       v_orditm_id_core dss.exchange_cores.orditm_id%TYPE; 
       v_order_id_core dss.orders.id%TYPE; 
       v_bltitm_id_core dss.po_histories.bltitm_id%TYPE; 

       v_order_type dss.orders.order_type%TYPE; 
       v_order_number dss.orders.order_number%TYPE; 

       v_order_id_xfer dss.orders.id%TYPE; 
       v_order_id_inbound dss.orders.id%TYPE; 
       v_orditm_id_po ordered_items.id%TYPE; 

       --anu 
       v_calc_freight number:=0; 
       v_method varchar2(4000); 

      BEGIN 

       FOR c_progpcon_rec IN c_progpcon 
       LOOP 

        v_cust_processed := v_cust_processed + 1; 
        SELECT orgrole_id 
        INTO v_orgrole_id_customer 
        FROM dss.customers 
        WHERE id = c_progpcon_rec.cust_id; 

        FOR c_custord_rec IN c_custord(v_orgrole_id_customer) 
        LOOP 

        v_custord_processed := v_custord_processed + 1; 

        -- outbound customer order 
        FOR c_outbound_rec IN c_outbound(c_custord_rec.order_id) 
        LOOP 
         begin 
          v_calc_freight:=DSS.PKG_ESTIMATED_FREIGHT.GET_ESTIMATED_FREIGHT 
             (null,c_outbound_rec.ship_id,v_method); 
          exception 
          when others then 
          v_calc_freight := 0; 

         end; 
         INSERT INTO adwaram.order_freight 
          (order_type 
          ,order_number 
          ,shipper_no 
          ,waybill 
          ,actual_freight 
          ,estimated_freight 
          ,waybill_entered 
          ,order_id 
          ,ship_id 
          ,shptrk_id 
          ,recshp_id 
          ,cust_id 
          ,order_id_cust 
          ,notes 
          ,dt_created) 
          VALUES 
          (c_custord_rec.order_type 
          ,c_custord_rec.order_number 
          ,c_outbound_rec.shipper_no 
          ,c_outbound_rec.waybill 
          ,c_outbound_rec.actual_freight 
          ,v_calc_freight--c_outbound_rec.estimated_freight 
          ,c_outbound_rec.dt_created 
          ,c_custord_rec.order_id 
          ,c_outbound_rec.ship_id 
          ,c_outbound_rec.shptrk_id 
          ,NULL 
          ,c_progpcon_rec.cust_id 
          ,c_custord_rec.order_id 
          ,'OUTBOUND CUST ORDER' 
          ,SYSDATE); 

        END LOOP; 

        FOR c_ordsch_rec IN c_ordsch(c_custord_rec.order_id) 
        LOOP 

         -- get core 
         BEGIN 

          SELECT xccore.orditm_id 
           ,pohist.bltitm_id 
          INTO v_orditm_id_po 
           ,v_bltitm_id_core 
          FROM dss.exchange_units xcunit 
           ,dss.exchange_cores xccore 
           ,dss.po_histories pohist 
          WHERE xcunit.ordsch_id = c_ordsch_rec.ordsch_id 
           AND xccore.xcitm_id = xcunit.xcitm_id 
           AND pohist.orditm_id(+) = xccore.orditm_id; 

          IF v_bltitm_id_core IS NOT NULL 
          THEN 
           v_order_id_core := dss.pkg_inven.func_get_order(v_bltitm_id_core 
                      ,'ORDER_ID'); 
           v_orditm_id_core := dss.pkg_inven.func_get_order(v_bltitm_id_core 
                       ,'ORDITM_ID'); 
          ELSE 
           v_order_id_core := NULL; 
          END IF; 

          IF v_order_id_core IS NOT NULL 
          THEN 

           -- outbound order for received core (repair order or customer order) 
           FOR c_outbound_rec IN c_outbound(v_order_id_core) 
           LOOP 
            begin 
             v_calc_freight:=DSS.PKG_ESTIMATED_FREIGHT.GET_ESTIMATED_FREIGHT 
             (null,c_outbound_rec.ship_id,v_method); 
             exception 
             when others then 
             v_calc_freight := 0; 

            end; 
           SELECT order_type 
             ,order_number 
            INTO v_order_type 
             ,v_order_number 
            FROM dss.orders 
            WHERE id = v_order_id_core; 

           INSERT INTO adwaram.order_freight 
            (order_type 
            ,order_number 
            ,shipper_no 
            ,waybill 
            ,actual_freight 
            ,estimated_freight 
            ,waybill_entered 
            ,order_id 
            ,ship_id 
            ,shptrk_id 
            ,recshp_id 
            ,cust_id 
            ,order_id_cust 
            ,notes 
            ,dt_created) 
            VALUES 
            (v_order_type 
            ,v_order_number 
            ,c_outbound_rec.shipper_no 
            ,c_outbound_rec.waybill 
            ,c_outbound_rec.actual_freight 
            ,v_calc_freight--c_outbound_rec.estimated_freight 
            ,c_outbound_rec.dt_created 
            ,v_order_id_core 
            ,c_outbound_rec.ship_id 
            ,c_outbound_rec.shptrk_id 
            ,NULL 
            ,c_progpcon_rec.cust_id 
            ,c_custord_rec.order_id 
            ,'OUTBOUND '||v_order_type||' ORDER' 
            ,SYSDATE); 

           END LOOP; 

          END IF; 

          -- xfer related to customer order 
          BEGIN 

           SELECT ord.id 
           INTO v_order_id_xfer 
           FROM dss.orders ord 
            ,dss.ordered_items orditm 
           WHERE ord.order_type = 'XFER' 
           AND ord.div_no = c_progpcon_rec.div_no 
           AND orditm.order_id = ord.id 
           AND orditm.customer_po = c_custord_rec.customer_po; 

           FOR c_outbound_rec IN c_outbound(v_order_id_xfer) 
           LOOP 
           begin 
            v_calc_freight:=DSS.PKG_ESTIMATED_FREIGHT.GET_ESTIMATED_FREIGHT 
              (null,c_outbound_rec.ship_id,v_method); 

            exception 
             when others then 
             v_calc_freight := 0; 

           end; 

           SELECT order_type 
             ,order_number 
            INTO v_order_type 
             ,v_order_number 
            FROM dss.orders 
            WHERE id = v_order_id_xfer; 

           INSERT INTO adwaram.order_freight 
            (order_type 
            ,order_number 
            ,shipper_no 
            ,waybill 
            ,actual_freight 
            ,estimated_freight 
            ,waybill_entered 
            ,order_id 
            ,ship_id 
            ,shptrk_id 
            ,recshp_id 
            ,cust_id 
            ,order_id_cust 
            ,notes 
            ,dt_created) 
            VALUES 
            (v_order_type 
            ,v_order_number 
            ,c_outbound_rec.shipper_no 
            ,c_outbound_rec.waybill 
            ,c_outbound_rec.actual_freight 
            ,v_calc_freight--c_outbound_rec.estimated_freight 
            ,c_outbound_rec.dt_created 
            ,v_order_id_xfer 
            ,c_outbound_rec.ship_id 
            ,c_outbound_rec.shptrk_id 
            ,NULL 
            ,c_progpcon_rec.cust_id 
            ,c_custord_rec.order_id 
            ,'OUTBOUND '||v_order_type||' ORDER' 
            ,SYSDATE); 

           END LOOP; 

          EXCEPTION 
           WHEN NO_DATA_FOUND 
            OR TOO_MANY_ROWS 
           THEN 
           NULL; 
          END; 


          -- inbound orders associate with exchange - v_orditm_id_core (if ro) 
          --           v_orditm_id_po (csp po) 
          IF v_orditm_id_core IS NOT NULL 
          THEN 

           FOR c_inbound_rec IN c_inbound(v_orditm_id_core) 
           LOOP 
            begin 
             v_calc_freight:=DSS.PKG_ESTIMATED_FREIGHT.GET_ESTIMATED_FREIGHT 
              (c_inbound_rec.recshp_id,null,v_method); 

             exception 
              when others then 
              v_calc_freight := 0; 

            end; 
           SELECT ord.order_type 
             ,ord.order_number 
             ,ord.id 
            INTO v_order_type 
             ,v_order_number 
             ,v_order_id_inbound 
            FROM dss.ordered_items orditm 
             ,dss.orders ord 
            WHERE orditm.id = v_orditm_id_core 
            AND ord.id = orditm.order_id; 

           INSERT INTO adwaram.order_freight 
            (order_type 
            ,order_number 
            ,shipper_no 
            ,waybill 
            ,actual_freight 
            ,estimated_freight 
            ,waybill_entered 
            ,order_id 
            ,ship_id 
            ,shptrk_id 
            ,recshp_id 
            ,cust_id 
            ,order_id_cust 
            ,notes 
            ,dt_created) 
            VALUES 
            (v_order_type 
            ,v_order_number 
            ,NULL 
            ,c_inbound_rec.waybill 
            ,c_inbound_rec.actual_freight 
            ,v_calc_freight--c_inbound_rec.estimated_freight 
            ,c_inbound_rec.dt_created 
            ,v_order_id_inbound 
            ,NULL 
            ,NULL 
            ,c_inbound_rec.recshp_id 
            ,c_progpcon_rec.cust_id 
            ,c_custord_rec.order_id 
            ,'INBOUND '||v_order_type||' ORDER' 
            ,SYSDATE); 

           END LOOP; 

          END IF; 

          IF v_orditm_id_po IS NOT NULL 
          THEN 

           FOR c_inbound_rec IN c_inbound(v_orditm_id_po) 
           LOOP 
           begin 
           v_calc_freight:=DSS.PKG_ESTIMATED_FREIGHT.GET_ESTIMATED_FREIGHT 
             (c_inbound_rec.recshp_id 
             ,NULL 
             , v_method 
             ); 
       exception 
         when others then 
         v_calc_freight := 0; 

         end; 

           SELECT ord.order_type 
             ,ord.order_number 
             ,ord.id 
            INTO v_order_type 
             ,v_order_number 
             ,v_order_id_inbound 
            FROM dss.ordered_items orditm 
             ,dss.orders ord 
            WHERE orditm.id = v_orditm_id_po 
            AND ord.id = orditm.order_id; 

           INSERT INTO adwaram.order_freight 
            (order_type 
            ,order_number 
            ,shipper_no 
            ,waybill 
            ,actual_freight 
            ,estimated_freight 
            ,waybill_entered 
            ,order_id 
            ,ship_id 
            ,shptrk_id 
            ,recshp_id 
            ,cust_id 
            ,order_id_cust 
            ,notes 
            ,dt_created) 
            VALUES 
            (v_order_type 
            ,v_order_number 
            ,NULL 
            ,c_inbound_rec.waybill 
            ,c_inbound_rec.actual_freight 
            ,v_calc_freight--c_inbound_rec.estimated_freight 
            ,c_inbound_rec.dt_created 
            ,v_order_id_inbound 
            ,NULL 
            ,NULL 
            ,c_inbound_rec.recshp_id 
            ,c_progpcon_rec.cust_id 
            ,c_custord_rec.order_id 
            ,'INBOUND '||v_order_type||' ORDER' 
            ,SYSDATE); 

           END LOOP; 

          END IF; 

         EXCEPTION 
          WHEN NO_DATA_FOUND 
           OR TOO_MANY_ROWS 
          THEN 
           NULL; 
         END; 

        END LOOP; 

        END LOOP; 

       END LOOP; 

       COMMIT; 
       dbms_output.put_line(TO_CHAR(v_cust_processed)||' customers processed.'); 
       dbms_output.put_line(TO_CHAR(v_custord_processed)||' customer orders processed.'); 

      END; 
      /
+0

はい、はるかに高速な方法があります...カーソルが遅い、別の方法を見つける。残念ながら、その大規模なスクリプトを通過する時間はありません – Twelfth

+0

私に例を教えてもらえますか? – Anu

+0

あなたはこの質問を数日前に聞いたことがありますが、削除したようです。明らかにあなたは満足のいく答えを得ておらず、あなたは今では得られないでしょう。これは疑問のない質問です。ビジネスルールの説明なしに、見知らぬ人が数百行の形式の整っていないコードをスクロールすることは合理的に期待できません。私たちはあなたのためにあなたの仕事をするためにここにいません。 – APC

答えて

1
  1. 、すべてのクエリの実行計画を確認し、彼らはBULKと予想
  2. 一括処理として を動作することを確認して、このOracle Magazine Articleはスティーブン・ファースタインによって で説明したように役立つかもしれCOLLECTとFORALL。
+0

はバルク収集を試みました。 取得エラー、IN 1 I1 FOR ... c_outbound_tab.count LOOP は を開始 - バルクIN 1 I1 FORALL を挿入.. c_outbound_tab.count PLS-00436:実装制限:BULKのフィールドを参照することはできませんのInレコードのBINDテーブル – Anu

+0

はすべてのコードを投稿できませんでした。 – Anu

+0

- pl/sqlテーブルを埋める OPEN c_outbound(c_custord_rec.order_id); FETCH c_outbound BULKはc_outbound_tabに集約されます。 CLOSE c_outbound; – Anu

関連する問題