我们的应用程序当前使用一个动态构建要执行的大部分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;
此设计是否改进了缓存/执行计划?是否需要进一步修改/调整以改进我们的软解析时间?
感谢所有反馈。