Sql 存储过程的Oracle性能调优
最近遇到的一个场景中,我有很多select语句,如下所示:Sql 存储过程的Oracle性能调优,sql,oracle,plsql,Sql,Oracle,Plsql,最近遇到的一个场景中,我有很多select语句,如下所示: and (UPPER(Table1.col1) LIKE UPPER(v_param1)||'%' or v_param1 is NULL) and (UPPER(Table2.col2) LIKE UPPER(v_param2)||'%' or v_param2 is NULL) v_param1和v_param2是存储过程的输入,我需要优化查询。是否有任何方法可以检查v_param1、v_param1是否为空,则无需在或之前检
and (UPPER(Table1.col1) LIKE UPPER(v_param1)||'%' or v_param1 is NULL)
and (UPPER(Table2.col2) LIKE UPPER(v_param2)||'%' or v_param2 is NULL)
v_param1
和v_param2
是存储过程的输入,我需要优化查询。是否有任何方法可以检查v_param1、v_param1是否为空,则无需在或之前检查第一个条件。删除该或并按如下方式更改条件
和upper(表1.col1)类似于upper(v_param1)| |'%
和upper(表2.col2)类似于upper(v_param2)| |'%
注意:如果param value为null,则它将执行类似“upper(col1)like“%”这样的条件。您可以做的最简单的事情是切换条件求值的顺序:
and (v_param1 is NULL or UPPER(Table1.col1) LIKE UPPER(v_param1)||'%' )
and (v_param2 is NULL or UPPER(Table2.col2) LIKE UPPER(v_param2)||'%' )
Oracle不保证会使OR计算短路,但以空测试为先导会让它朝着正确的方向前进 如果使用存储过程,则可以在pl/sql中动态构造查询,绑定变量并使用dbms\U sql执行查询
...
sSQL varchar2(32767) := 'select col1, col2 from Table1';
iCurrId number := DBMS_SQL.OPEN_CURSOR;
iCurRes number;
begin
-- constant conditions
sSQL := sSQL||' where col3 = :column3_value';
-- add condition for v_param1 if it is not null
if v_param1 is not null then
sSQL := sSQL||' and UPPER(Table1.col1) LIKE :v_param1_search_value';
end if;
-- add condition for v_param2 if it is not null
if v_param2 is not null then
sSQL := sSQL||' and UPPER(Table1.col2) LIKE :v_param2_search_value';
end if;
-- parse cursor
DBMS_SQL.PARSE(
C => iCurrId,
STATEMENT => sSQL,
LANGUAGE_FLAG => DBMS_SQL.NATIVE
);
-- bind variables
DBMS_SQL.BIND_VARIABLE( C => iCurrId, NAME => 'column3_value', VALUE => 'abcd');
if v_param1 is not null then
DBMS_SQL.BIND_VARIABLE( C => iCurrId, NAME => 'v_param1_search_value', VALUE => UPPER(v_param1)||'%');
end if;
if v_param2 is not null then
DBMS_SQL.BIND_VARIABLE( C => iCurrId, NAME => 'v_param2_search_value', VALUE => UPPER(v_param2)||'%');
end if;
-- execute query
iCurRes := DBMS_SQL.EXECUTE(iCurrId);
...
尝试使用:
AND (
CASE
WHEN v_param2 IS NULL
THEN NULL
ELSE UPPER(Table2.col2)
END LIKE UPPER(v_param2)
||'%'
OR v_param2 IS NULL)
您可以做的一件事是根据第1列和第2列的上限为响应创建一个基于函数的索引,这不符合我的要求,因为有很多选择with and子句,在这些选择with and子句上创建索引会降低其他服务对这些表执行insert或update操作的性能。您不能以大写形式存储Table1.col1和Table1.col2吗。这将避免在查询期间将它们转换为大写的过载。