如何优化循环,即在Oracle中调用对象?

时间:2016-10-26 09:15:49

标签: sql oracle plsql sql-tuning query-tuning

以下是需要优化的代码。

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 个答案:

答案 0 :(得分:1)

我发现你有一个带有删除更新插入的巨大循环。

  1. 在任何操作之后,你调用commit。在oracle中,最好在事务结束时只使用一次提交。
  2. 此外,您逐行更新,但最好尝试在一个合并语句中更新,插入和删除。