2016-10-26 3 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 лучше использовать только одну фиксацию в конце транзакции.
  2. Кроме того, вы обновляете строку за строкой, но лучше пытаетесь обновить, вставить и удалить в одном операторе слияния.
Смежные вопросы