我在DB2 sql中遇到了一个奇怪的行为。 (DB2 9.7) Follow是一个获取员工薪水,状态和乐队的示例查询。
SELECT
EMP.STATUS,
COUNT(*) AS EMP_COUNT,
GRP.GROUP_NAME
FROM
EMPLOYEE EMP,
EMPLOYEE_SALARY ES,
GROUP_TABLE GRP
WHERE
EMP.SALARY >
(select max(EMP1.SALARY) from
EMPLOYEE EMP1, FINANCIAL_YEAR FY where
date(EMP1.JOIN_DT) = '2013-01-01'
and date(EMP1.DATE_TS) = date(FY.CURRENT_DT) - 2 days)
AND EMP.SALARY = E.EMPID
AND E.SALARY_GRP = GRP.BAND_GROUP
AND GRP.RANGE_SALARY = 'BAND-10'
GROUP BY
EMP.STATUS,
GRP.GROUP_NAME
EMP(员工)表包含大约1百万行。其余的表非常小。 查询大约需要10秒才能执行
但是当我对内部查询进行硬编码时
这
select max(EMP1.SALARY) from EMPLOYEE EMP1, FINANCIAL_YEAR FY where
date(EMP1.JOIN_DT) = '2013-01-01'
and date(EMP1.DATE_TS) = date(FY.CURRENT_DT) - 2 days
到
select max(EMP1.SALARY) from EMPLOYEE EMP1, FINANCIAL_YEAR FY where
date(EMP1.JOIN_DT) = '2013-01-01'
and date(EMP1.DATE_TS) = '2013-06-01'
结果在一秒钟之内!!
“FINANCIAL_YEAR FY”表是一个非常小的表,大约有50行,因此我不知道为什么内部查询在其动态时需要时间,但在我硬编码时非常快
一些额外的信息
答案 0 :(得分:0)
您可以尝试使用此版本(我假设E
引用应该是ES
别名,否则语句不应该运行。除此之外,你应该放弃隐含的联接' (以逗号分隔的FROM
子句),特别是如果您开始处理LEFT JOIN
s。
WITH Maximum_Salary (max) as (SELECT MAX(EMP.SALARY)
FROM EMPLOYEE EMP
JOIN FINANCIAL_YEAR FY
ON (FY.CURRENT_DT - 2 DAYS) >= EMP.DATE_TS
AND (FY.CURRENT_DT - 1 DAYS) < EMP.DATE_TS
WHERE EMP.JOIN_DT = DATE('2013-01-01')
SELECT EMP.STATUS, COUNT(*) AS EMP_COUNT, GRP.GROUP_NAME
FROM EMPLOYEE EMP
JOIN GROUP_TABLE GRP
ON GRP.RANGE_SALARY = 'BAND-10'
JOIN EMPLOYEE_SALARY ES
ON ES.EMPID = EMP.SALARY
AND ES.SALARY_GRP = GRP.BAND_GROUP
JOIN Maximum_Salary
ON Maximum_Salary <= EMP.SALARY
GROUP BY EMP.STATUS, GRP.GROUP_NAME
如果您还没有习惯,WITH
语法是公用表表达式(或CTE) - 实际上,它是一个内联视图。在某些情况下,这些可以导致创建临时表,但是否则可以节省大量的输入(它们也是如何执行递归查询)。我设法将EMP.DATE_TS
的引用转换为可以使用索引的表单(对FY.CURRENT_DT
上的日期数学没有帮助,尽管作为一个不应该使用的小表很重要。)
请注意,您可能仍需要执行其他调整,尤其是取决于您可能(不)具有哪些索引。