如何优化我的存储过程

时间:2015-07-30 00:13:51

标签: oracle stored-procedures

我想知道是否有方法可以优化n提高此存储过程的性能。我对此非常陌生。非常感谢你的帮助

总结一下,存储过程采用数组。每个数组都是a:b:c形式的一个条目。在提取所需数据之后,在表格中进行输入。

create or replace 
PROCEDURE insert_sku_prom_assigments (
   sku_assigment_array         tp_string_array_table
)
IS
first_colon_pos    NUMBER;
second_colon_pos   NUMBER;
sku                VARCHAR2 (40);
assign             VARCHAR2 (20);
promotion          VARCHAR2 (40);
l_count            INTEGER;
 BEGIN
FOR i IN sku_assigment_array.FIRST .. sku_assigment_array.LAST
 LOOP
  first_colon_pos := INSTR (sku_assigment_array (i), ':', 1, 1);
  second_colon_pos := INSTR (sku_assigment_array (i), ':', 1, 2);
  sku := SUBSTR (sku_assigment_array (i), 1, first_colon_pos - 1);
  assign :=
     SUBSTR (sku_assigment_array (i),
             first_colon_pos + 1,
             second_colon_pos - first_colon_pos - 1
            );
  promotion := SUBSTR (sku_assigment_array (i), second_colon_pos + 1);

  IF sku IS NOT NULL AND assign IS NOT NULL AND promotion IS NOT NULL
  THEN
     SELECT COUNT (*)
       INTO l_count
       FROM mtep_sku_promotion_rel_unver
      WHERE sku_id = sku
        AND assignment = assign
        AND promotion_id = promotion
        AND ROWNUM = 1;

     IF l_count < 1
     THEN
        INSERT INTO mtep_sku_promotion_rel_unver
                    (sku_id, assignment, promotion_id
                    )
             VALUES (sku, assign, promotion
                    );
     END IF;
  END IF;

  l_count := 0;
END LOOP;
END insert_sku_prom_assigments;

2 个答案:

答案 0 :(得分:1)

@jorge是对的,可能没有太多的性能提升。但是在插入之前你可以考虑选择计数的这些替代方案:

此:

INSERT INTO mtep_sku_promotion_rel_unver
                (sku_id, assignment, promotion_id
                )
SELECT sku, assign, promotion FROM DUAL
WHERE NOT EXISTS
( SELECT NULL
    FROM mtep_sku_promotion_rel_unver
   WHERE sku_id = sku
     AND assignment = assign
     AND promotion_id = promotion
);

或者,假设这3列被定义为键:

BEGIN
  INSERT INTO mtep_sku_promotion_rel_unver
                (sku_id, assignment, promotion_id
                )
         VALUES (sku, assign, promotion
                );
EXCEPTION
  WHEN DUP_VAL_ON_INDEX THEN NULL;
END;

这与性能无关,但我也想使用Oracle函数apex_util.string_to_table轻松分解分隔的字符串:

PROCEDURE ...
IS
  v_tab apex_application_global.vc_arr2;
  ...
BEGIN
  v_tab := apex_util.string_to_table (sku_assigment_array (i), ':');
  if v_tab.count >= 3 then
    sku := v_tab(1);
    assign := v_tab(2);
    promotion := v_tab(3);
  end if;

答案 1 :(得分:1)

用一个SQL语句替换逐行PL / SQL:

["objectId"]

以下是测试的示例对象:

create or replace procedure insert_sku_prom_assigments
(
    sku_assigment_array tp_string_array_table
) is
begin
    --#4: Insert new SKU, ASSIGN, and PROMOTION.
    insert into mtep_sku_promotion_rel_unver(sku_id, assignment, promotion_id)
    select sku, assign, promotion
    from
    (
        --#3: Get values.
        select sku_string,
            substr (sku_string, 1, first_colon_pos - 1) sku,
            substr (sku_string, first_colon_pos + 1, second_colon_pos-first_colon_pos - 1) assign,
            substr (sku_string, second_colon_pos + 1) promotion
        from
        (
            --#2: Get positions.
            select
                sku_string,
                instr(sku_string, ':', 1, 1) first_colon_pos,
                instr(sku_string, ':', 1, 2) second_colon_pos
            from
            (
                --#1: Convert collection to table.
                select column_value sku_string
                --Use this for debugging:
                --from table(tp_string_array_table('asdf:qwer:1234'))
                from table(sku_assigment_array)
            ) converted_collection
        ) positions
    ) sku_values
    --Only non-null values:
    where sku is not null and assign is not null and promotion is not null
    --Row does not already exist:
    and not exists
    (
        select 1/0
        from mtep_sku_promotion_rel_unver
        where sku_id = sku
            and assignment = assign
            and promotion_id = promotion
    );
end insert_sku_prom_assigments;
/

SQL几乎总是优于PL / SQL。一旦习惯了代码流的方式,它也更容易测试和调试。