为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】:V8 BUILD_TIME Apr 8 2024 11:25:57
【操作系统】:WIN10
【CPU】:
【问题描述】*:当我使用达梦数据当做工具类,查询工作日时,工作日表只有一万多条数据,具体sql如下:
SELECT MAX(T.FDATE) AS VD_RDATE
INTO VD_RDATE
FROM TS_DATES T
WHERE T.DATE_TYPE = '00035001'
AND T.WORK_DAY_NO = '0' ;
然后存储过程将VD_RDATE返回
完整的查询语句是:
select * from test_table where test_date= TEST_UTILS.FUN_GETWORKDAY(sysdate , -2);
这样的sql查询很慢很慢,请问这是什么原因呢
看下执行计划
分别执行下看是慢在哪个部分
--1
select TEST_UTILS.FUN_GETWORKDAY(sysdate , -2);
--2
select MAX(T.FDATE) AS VD_RDATE
FROM TS_DATES T
WHERE T.DATE_TYPE = '00035001'
AND T.WORK_DAY_NO = '0';
--3
select * from test_table where test_date= (select MAX(T.FDATE) AS VD_RDATE
FROM TS_DATES T
WHERE T.DATE_TYPE = '00035001'
AND T.WORK_DAY_NO = '0')
修改存储过程 TEST_UTILS.FUN_GETWORKDAY,勾选“确定函数” 试试看
做个实验,修改一下查询条件,然后看看查询耗时是否有所改善
select * from test_table where test_date= (SELECT TEST_UTILS.FUN_GETWORKDAY(sysdate , -2));
我刚在手头测试库里做了个实验,初步估计是直接调用函数结果作为条件值时,函数会被循环调用,这样累积耗时就变得很长了
而将函数迁入到子查询内,则改函数将只调用一次
我手头测试库版本为: --03134284172-20240321-222308-20093
下面是我测试的过程:
--创建测试表
CREATE TABLE T_TST1
(
A VARCHAR2(100)
);
--插入4条测试数据
INSERT INTO T_TST1 VALUES('A'),('B'),('C'),('D');
COMMIT;
--创建验证用函数
CREATE OR REPLACE FUNCTION F_TST1
RETURN VARCHAR2
IS
V_RET VARCHAR2(255);
BEGIN
--这里输出1,用来确认函数被调用次数
PRINT(1);
SELECT MAX(A)
INTO V_RET
FROM T_TST1;
RETURN V_RET;
END;
--直接引用函数返回结果作为参数值
--输出4个1,等于函数被调用4次
SELECT *
FROM T_TST1
WHERE A = F_TST1;
--将函数包在子查询中,再以子查询结果作为条件参数
--输出1个1
SELECT *
FROM T_TST1
WHERE A = (SELECT F_TST1)
test_table 这个表也只有1000条数据,但是整个流程查询下来需要8秒多,很奇怪