包与过程中的动态SQL语句性能

时间:2014-09-30 11:01:14

标签: sql oracle dynamic oracle11g package

我们的应用程序当前使用一个动态构建要执行的大部分SQL语句的过程。这个程序每个周末执行大约10,000次。

问题:最近我们的DBA注意到这个程序执行的Soft Parse时间很多,他建议我们使用一个Package,为每个输入组合构建一次sql语句。这是因为只有有限数量的可能输入组合。但他非常不确定需要为此设计设置哪些其他参数以及SQL的缓存如何工作。

目前的程序粗略地看起来像:

Procedure P (v1 IN NUMBER, v2, IN NUMBER)
    v_table_name            VARCHAR2(30);

    v_table_name := 'X' || v1;
    v_sql = ' INSERT INTO ' || v_table_name || 'values..';
    EXECUTE IMMEDIATE v_sql USING aaa;

    v_table_name := 'Y' || v2;
    v_sql = ' SELECT abc FROM ' || v_table_name ;
    EXECUTE IMMEDIATE v_sql
    INTO bbb USING kkk;
END;

因此,基于这些建议,替换它的新包应该如下所示:

PACKAGE BODY PK AS

v_sql_1 VARCHAR2 := '';
v_sql_2 VARCHAR2 := '';
v_sql_3 VARCHAR2 := '';.... many more

PROCEDURE P (v1 IN NUMBER, v2, IN NUMBER)
IF (*condition A*) THEN         <Conditions can occur many times>
   IF (v_sql_1 = '') THEN
      v_sql_1 := 'INSERT INTO ' || v_table_name ||...  <Construct once>        
      EXECUTE IMMEDIATE v_sql_1 USING aaa;
   ELSE
      EXECUTE IMMEDIATE v_sql_1 USING aaa;
   END IF;
END IF;

IF (*condition B*) THEN
   IF (v_sql_2 = '') THEN
      v_sql_2 := 'SELECT abc FROM ' || v_table_name....  <Construct once>        
      EXECUTE IMMEDIATE v_sql INTO bbb USING kkk;
   ELSE
      EXECUTE IMMEDIATE v_sql INTO bbb USING kkk;
   END IF;
END IF;

此设计是否改进了缓存/执行计划?是否需要进一步修改/调整以改进我们的软解析时间?

感谢所有反馈。

0 个答案:

没有答案