【发布时间】:2013-06-03 13:53:00
【问题描述】:
我在 DB2 sql 中遇到了一个奇怪的行为。 (DB2 9.7) 以下是获取员工工资、状态和乐队的示例查询。
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(员工)表包含大约 100 万行。其余的桌子都很小。 执行查询大约需要 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 行,因此我不知道为什么内部查询在动态时需要时间,但在我硬编码时非常快
一些附加信息
- EMPID 是整数
- DATE_TS 是时间戳
- CURRENT_DT,JOIN_DT 是日期
- 其余都是 VARCHAR
- EMPID 已编入索引
【问题讨论】:
-
EMP1.JOIN_DT、EMP1.DATE_TS和FY.CURRENT_DT的数据类型是什么?什么是示例值? (问题的原因是在要加入的字段上调用函数DATE,这样做会破坏使用索引的能力。) -
@Dems 我最初也想过。但是当我硬编码时它完全一样吗? FY.CURRENT_DT 如果单独查询将在毫秒内到达。
-
您看过访问计划吗?它说什么?
-
将执行计划粘贴到您的问题中。我认为内部 SELECT 语句必须每行执行一次。这无疑是性能杀手。
-
DB2 优化器可能能够在您进行硬编码时“作弊”,通过替换范围查询(现在,看,我不知道它是否实际上可以)。
标签: sql performance db2