0

更新:伙计们,我正在将教员 ID 列表传递给存储过程,当我传递超过 10 个教员 ID 时,处理数据需要很长时间并且有时会超时。我花了很多时间调试这个查询,发现 proc 中的最后一行导致查询超时/响应时间慢。最后一行是 CTE 的子查询。如何重写/优化 proc 的最后一行以使我的查询运行得更快。任何帮助将不胜感激。有人可以帮忙吗?

create or replace PROCEDURE sp_Test(
facultycode IN  varchar2
//few more variables
---
---
p_result OUT sys_refcursor
)
AS
open recordset for 
//this parses list of id's i.e('101''102''104'108') and i am calling this in last line of my proc
with faculty_list as (
SELECT REGEXP_SUBSTR(facultycode,'[^,]+',1,LEVEL) AS FAC_CODE
         FROM DUAL              
    CONNECT BY LEVEL <=LENGTH (REGEXP_REPLACE(facultycode,'[^,]+'))+1
    )

select s.s_name, m.score, s.status
 from student s 
join marks m on s.s_id = m.s_id 
WHERE S.GRADE>5
AND facultycode is null or s.fac_code in (select FAC_CODE from faculty_list); //this line 
is making query very slow, I need to optimize this line for faster response
END sp_Test;
4

1 回答 1

1

您可以尝试在有子句子查询的 Faculty_list 上使用 /*+ MATERIALIZE */ 提示。一般来说,我会说表现主要取决于student.faculty_code是否被索引,你可以在这个索引中添加成绩

create index student_fac_grade_idx on student (fac_code, grade);

如果你有这个指数和物化兴,那么你有最佳机会表现良好。以下也适用于空输入列表:

with in_list as
(
select '101,102,104,108,201,202,204,208,301,402,504,608' in_list from dual
--select '' in_list from dual
)
, faculty_list as 
(
SELECT /*+ MATERIALIZE */ REGEXP_SUBSTR(in_list,'[^,]+',1,LEVEL) AS FAC_CODE
         FROM DUAL , in_list    
    CONNECT BY LEVEL <=LENGTH (REGEXP_REPLACE(in_list,'[^,]+'))+1
)
--select * from faculty_list ;
, student as
(
select 1 s_id, 'Joe' s_name, 'ACTIVE' status , 6 grade, 101 fac_code from dual
)
, marks as
(
select 1 s_id, 100 score from dual
)
/* main query */
select s.s_name, m.score, s.status
from student s 
join marks m on s.s_id = m.s_id 
WHERE S.GRADE>5
and (s.fac_code in (select FAC_CODE from faculty_list)
or (select fac_code from faculty_list ) is null)
;
于 2020-03-16T16:58:26.017 回答