2016-10-26 12 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. 어떤 작업이 있은 후에 커밋을 호출합니다. 오라클에서는 트랜잭션이 끝날 때 하나의 커밋을 사용하는 것이 좋습니다.
  2. 게다가 행별로 업데이트하지만 더 잘 업데이트하려고하면 병합 문 하나에 삽입하고 삭제하십시오.