在 Oracle 中使用 datediff 函数时查询速度慢
Slow query when using datediff function in Oracle
作为我的标题,我有以下代码:
SELECT
*
FROM
de.Department
WHERE
de.flag = 1
AND de.DepartmentNum IN (10,4)
AND de.status IN (0,-1,100)
AND datediff('dd',de.datequit,'30-SEP-19') > 9
datediff 函数使我的查询 运行 非常慢(11 条记录需要 16 秒),并且成本也非常高(~43k)。
这是我的 datediff 函数代码
create or replace FUNCTION DATEDIFF
(
P_TYPE_DATE IN VARCHAR2
, P_START_DATE IN TIMESTAMP
, P_END_DATE IN TIMESTAMP
) RETURN NUMBER AS
v_Result NUMBER := -1;
BEGIN
IF P_TYPE_DATE IS NOT NULL AND P_START_DATE IS NOT NULL AND P_END_DATE IS NOT NULL THEN
CASE UPPER(P_TYPE_DATE)
WHEN 'DD' THEN RETURN ROUND(TRUNC(P_END_DATE,'DD') - TRUNC(P_START_DATE,'DD'),0);
WHEN 'HH' THEN RETURN ROUND((TRUNC(P_END_DATE,'HH') - TRUNC(P_START_DATE,'HH')) * 24,0);
WHEN 'MI' THEN RETURN ROUND((TRUNC(P_END_DATE,'MI') - TRUNC(P_START_DATE,'MI')) * 24 * 60,0);
WHEN 'SS' THEN RETURN ROUND((TRUNC(P_END_DATE,'MI') - TRUNC(P_START_DATE,'MI')) * 24 * 60 * 60 + extract(second from (P_END_DATE - P_START_DATE)),0);
ELSE RETURN NULL;
END CASE;
END IF;
RETURN NULL;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
END DATEDIFF;
我用了SELECT *因为我想得到部门table的几乎专栏,所以如果我SELECT一些我需要的专栏就不会再改变了。
我可以re-write提高性能和成本吗?
非常感谢!
I created a function named datediff as a datediff function in SQL, sir
不要使用自定义函数,因为它们会阻止 Oracle 在列上使用索引;而只是将列与静态值进行比较:
SELECT *
FROM Department
WHERE flag = 1
AND DepartmentNum IN (10,4)
AND status IN (0,-1,100)
AND datequit > DATE '2019-09-30' + INTERVAL '9' DAY
或
AND datequit > DATE '2019-09-30' + NUMTODSINTERVAL( 9, 'DAY' )
或
AND datequit > DATE '2019-09-30' + 9
Here is my datediff function code
...
WHEN 'DD' THEN RETURN ROUND(TRUNC(P_END_DATE,'DD') - TRUNC(P_START_DATE,'DD'),0);
...
如果您想使用 TRUNC
进行等效比较以忽略时间分量,则从使用大于比较更改为使用大于或等于并添加一个时间单位 (在你的例子中的一天)到预期的差异。例如:
SELECT *
FROM Department
WHERE flag = 1
AND DepartmentNum IN (10,4)
AND status IN (0,-1,100)
AND datequit >= DATE '2019-09-30' + INTERVAL '10' DAY
作为我的标题,我有以下代码:
SELECT
*
FROM
de.Department
WHERE
de.flag = 1
AND de.DepartmentNum IN (10,4)
AND de.status IN (0,-1,100)
AND datediff('dd',de.datequit,'30-SEP-19') > 9
datediff 函数使我的查询 运行 非常慢(11 条记录需要 16 秒),并且成本也非常高(~43k)。
这是我的 datediff 函数代码
create or replace FUNCTION DATEDIFF
(
P_TYPE_DATE IN VARCHAR2
, P_START_DATE IN TIMESTAMP
, P_END_DATE IN TIMESTAMP
) RETURN NUMBER AS
v_Result NUMBER := -1;
BEGIN
IF P_TYPE_DATE IS NOT NULL AND P_START_DATE IS NOT NULL AND P_END_DATE IS NOT NULL THEN
CASE UPPER(P_TYPE_DATE)
WHEN 'DD' THEN RETURN ROUND(TRUNC(P_END_DATE,'DD') - TRUNC(P_START_DATE,'DD'),0);
WHEN 'HH' THEN RETURN ROUND((TRUNC(P_END_DATE,'HH') - TRUNC(P_START_DATE,'HH')) * 24,0);
WHEN 'MI' THEN RETURN ROUND((TRUNC(P_END_DATE,'MI') - TRUNC(P_START_DATE,'MI')) * 24 * 60,0);
WHEN 'SS' THEN RETURN ROUND((TRUNC(P_END_DATE,'MI') - TRUNC(P_START_DATE,'MI')) * 24 * 60 * 60 + extract(second from (P_END_DATE - P_START_DATE)),0);
ELSE RETURN NULL;
END CASE;
END IF;
RETURN NULL;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
END DATEDIFF;
我用了SELECT *因为我想得到部门table的几乎专栏,所以如果我SELECT一些我需要的专栏就不会再改变了。
我可以re-write提高性能和成本吗?
非常感谢!
I created a function named datediff as a datediff function in SQL, sir
不要使用自定义函数,因为它们会阻止 Oracle 在列上使用索引;而只是将列与静态值进行比较:
SELECT *
FROM Department
WHERE flag = 1
AND DepartmentNum IN (10,4)
AND status IN (0,-1,100)
AND datequit > DATE '2019-09-30' + INTERVAL '9' DAY
或
AND datequit > DATE '2019-09-30' + NUMTODSINTERVAL( 9, 'DAY' )
或
AND datequit > DATE '2019-09-30' + 9
Here is my datediff function code
... WHEN 'DD' THEN RETURN ROUND(TRUNC(P_END_DATE,'DD') - TRUNC(P_START_DATE,'DD'),0); ...
如果您想使用 TRUNC
进行等效比较以忽略时间分量,则从使用大于比较更改为使用大于或等于并添加一个时间单位 (在你的例子中的一天)到预期的差异。例如:
SELECT *
FROM Department
WHERE flag = 1
AND DepartmentNum IN (10,4)
AND status IN (0,-1,100)
AND datequit >= DATE '2019-09-30' + INTERVAL '10' DAY