2016-10-26 11 views
0

以下は最適化が必要なコードです。Oracleでオブジェクトを呼び出すループを最適化するにはどうすればよいですか?

for i in 1 .. p_in_util_data_list(j).factlist.count LOOP 
      SELECT count(*) 
       INTO v_non_factor_exists 
       FROM engine_usage_factors 
      WHERE usage_month = v_usage_month 
       AND contract_seq_id = p_in_contractId 
       AND engine_serial_number = p_in_util_data_list(j).esn 
       AND nvl(upper(subfleet_id), 'X') = 
        nvl(upper(p_in_util_data_list(j).fleet), 'X') 
       AND nvl(upper(tail_number), 'X') = 
        nvl(upper(p_in_util_data_list(j).tail), 'X') 
       AND nvl(upper(factor_name), 'X') = 
        nvl(upper(p_in_util_data_list(j).factlist(i).name), 'X') 
       AND avg_flag = 'N' 
       AND recon_ind = 0; 

      IF v_non_factor_exists > 0 THEN 
       DELETE FROM engine_usage_factors 
       WHERE usage_month = v_usage_month 
       AND contract_seq_id = p_in_contractId 
       AND engine_serial_number = p_in_util_data_list(j).esn 
       AND nvl(upper(subfleet_id), 'X') = 
        nvl(upper(p_in_util_data_list(j).fleet), 'X') 
       AND nvl(upper(tail_number), 'X') = 
        nvl(upper(p_in_util_data_list(j).tail), 'X') 
       AND nvl(upper(factor_name), 'X') = 
        nvl(upper(p_in_util_data_list(j).factlist(i).name), 
         'X') 
       AND avg_flag = 'N' 
       AND recon_ind = 0; 
       COMMIT; 
      END IF; 

      IF UPPER(P_IN_UTIL_DATA_LIST(J).FACTLIST(I).NAME) = 'THRUST' THEN 
       V_VALUE := 0; 
      ELSE 
       V_VALUE := P_IN_UTIL_DATA_LIST(J).FACTLIST(I).VALUE; 
      END IF; 


      IF UPPER(p_in_util_data_list(j).factlist(i).name) = 'THRUST' THEN 



       UPDATE engine_usage 
       SET THRUST_RATING = p_in_util_data_list(j).factlist(i) 
             .value, 
        last_updated_by = p_in_login_id, 
        last_update_date = sysdate 
       WHERE usage_month = v_usage_month 
       AND engine_serial_number = 
        trim(p_in_util_data_list(j).esn) 
       AND recon_ind = 0 
       AND from_date = v_from_date 
       AND contract_seq_id = p_in_contractId 
       AND hybrid_payment_type = p_in_billingType; 
       COMMIT; 



       v_value := 0; 

      END IF; 

      INSERT INTO engine_usage_factors 
       (usage_month, 
       contract_seq_id, 
       engine_serial_number, 
       subfleet_id, 
       tail_number, 
       factor_name, 
       factor_value, 
       recon_ind, 
       from_date, 
       avg_flag, 
       created_by, 
       created_date, 
       last_updated_by, 
       last_update_date) 
      values 
       (v_usage_month, 
       p_in_contractId, 
       p_in_util_data_list(j).esn, 
       p_in_util_data_list(j).fleet, 
       NVL(p_in_util_data_list(j).tail, 'DUMMY'), 
       p_in_util_data_list(j).factlist(i).name, 
       v_value, 
       0, 
       v_from_date, 
       'N', 
       p_in_login_id, 
       sysdate, 
       p_in_login_id, 
       sysdate); 

      commit; 
      END LOOP; 

このループは700回呼び出され、多くの時間がかかります。

+1

最も遅い部分を特定しようとします(選択、削除、更新?)。また、ループを繰り返す必要があるのでしょうか、あるいは、異なる構造のバルク操作でソリューションを再考することはできますか?コミット後にステートメントがエラーを出した場合はどうなりますか?あなたは部分コミットをするでしょう、これはあなたが必要とするものですか? – Aleksej

+0

ループが終了した後にコミットを試みます。 – wieseman

+0

@ Aleksej-ありがとうございました!どうすればループを置き換えることができますか教えていただけますか?ループは0から700の範囲で実行されます。 – CodERORR

答えて

1

まあ、私はあなたが削除更新インサートで巨大なループを参照してください参照してください。

  1. 任意のオペレーションの後、コミットを呼び出します。 Oracleでは、トランザクションの終了時に1つのコミットを使用するほうがよい。
  2. さらに、行単位で更新しますが、更新する方がよい場合は、1つのマージステートメントで挿入して削除してください。
関連する問題