【发布时间】:2019-01-24 22:32:52
【问题描述】:
我需要查询一个表,并且可以在 WHERE 子句中传递一个或最多六个参数,具体取决于前端选择的选项。我在 WHERE 子句中使用了 CASE 语句来处理所有排列。
这里是SP代码sn-p:
create procedure return_data (
p_field1 in varchar(20),
p_field2 in varchar2(30),
p_field3 in varchar2(30),
cur out sys_refcursor)
is
begin
open cur for
select col1, col2, col3,col4,col5,col6
from master_table
where (case when (p_field1 is null) then (1)
when (p_field1 is not null) and (col1=p_field1) then 1
else 0 end) =1
and (case when (p_field2 is null) then (1)
when (p_field2 is not null) and (col2=p_field2) then 1
else 0 end) =1
... so one repeat for all columns.
但是,master_table 有超过 500 万行,所以我在每个搜索字段上创建了一个索引,但存储过程没有使用索引并且正在执行全表扫描,导致性能下降。
如果我从 WHERE 子句中删除 CASE 语句并传递类似 where col1=p_field1) 的内容,则使用索引并且查询性能非常好。
但是,由于并非所有输入字段都是前端必填项,因此我必须在 WHERE 子句中使用 CASE 语句。
准确地说,在 WHERE 子句中使用 CASE 语句,Oracle 没有使用索引。
有人可以建议如何调整上面的 sql 以便它使用索引来提高性能吗?
提前致谢。
【问题讨论】:
-
你需要创建一个Function-based index
-
为什么在 where 子句中使用 case stmt?
-
我正在使用 case stmt,因为并非所有字段都始终作为输入传递。如果该值被传递,我需要将它与数据库进行匹配,否则该字段不应包含在“where”条件中。
-
您可以将您的条件写成
(p_field1 is null or col1=p_field1)
标签: oracle performance indexing query-optimization oracle12c