【发布时间】:2020-10-02 08:55:42
【问题描述】:
我有一个如下所示的 Oracle SQL 查询,
select *
from employees a, department b
where a.empoyee_id = 10
and a.dept_no = b.dept_no
and a.salary between 10000 and 20000
and a.start_date between date1 and date2
and a.end_date between date3 and date4
以上查询运行良好,几秒钟内即可获取结果。
但如果将其转换为如下所示的存储过程,
Procedure GETDATA(
EMP_ID IN NUMBER,
MIN_SAl IN NUMBER,
MAX_SAL IN NUMBER,
MIN_START_DATE IN VARCHAR2,
MAX_START_DATE IN VARCHAR2,
MIN_END_DATE IN VARCHAR2,
MAX_END_DATE IN VARCHAR2,
RESULT OUT dataset
)
IS
BEGIN
open RESULT FOR
select * from employees a, department b
where EMPLOYEE_ID = EMP_ID AND a.dept_no = b.dept_no
and (MIN_SAl IS NULL OR MAX_SAL IS NULL) OR (a.salary between MIN_SAl and MAX_SAL)
and (MIN_START_DATE IS NULL OR MAX_START_DATE IS NULL) OR (a.start_date between MIN_START_DATE and MAX_START_DATE)
and (MIN_END_DATE IS NULL OR MAX_END_DATE IS NULL) OR (a.end_date between MIN_END_DATE and MAX_END_DATE);
END GETDATA;
exec GETDATA(10, NULL, NULL, NULL, NULL, NULL, NULL, :p)
上面的存储过程需要 10 多秒,但单独运行它会在几秒钟内得到结果。我看到为 where 子句(salary、start_date、end_date)中的所有列添加了索引
我发现日期标准需要更多时间。我用谷歌搜索并将 start_date 和 end_date 数据类型从 VARCHAR 修改为 DATE,但仍然没有运气。为什么在存储过程中花费更多时间,但在几秒钟内独立运行?
【问题讨论】:
-
查询类似但不一样:请使用stackoverflow.com/questions/34975406/…发布执行计划
-
要验证问题到底出在哪里,请将此查询作为游标运行,然后遍历游标并查看需要多少时间。同样按照建议粘贴此查询的执行计划。
-
我相信你有括号错误。不应该是
AND (min_x IS NULL OR max_x IS NULL or x BETWEEN min_x AND max_x)吗?
标签: sql oracle stored-procedures plsql