2013-06-03 100 views
0

我在DB2 sql中遇到了一個奇怪的行爲。 (DB2 9.7) 遵循的是一個簡單的查詢來獲取員工工資,地位和帶..DB2內部查詢速度慢但硬編碼值很快

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萬左右行。其餘桌子非常小。 查詢約需10secs執行

但是,當我硬編碼的內部查詢

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風雲」表是一個非常小桌子與約50行,所以我不知道爲什麼內查詢所花費的時間本身時,其動態的,但速度非常快,當我硬編碼

一些附加信息

  • EMPID是整數
  • DATE_TS是時間戳
  • CURRENT_DT,JOIN_DT是日期
  • 其餘全部都是VARCHAR
  • EMPID被索引
+0

「EMP1.JOIN_DT」,「EMP1.DATE_TS」和「FY.CURRENT_DT」的數據類型是什麼?什麼是示例值? *(你的問題的原因是你正在加入的字段上調用函數「DATE」,這樣做會破壞**使用索引的能力。)* – MatBailie

+0

@Dems我最初的想法是。但是,當我的硬編碼是完全一樣的?如果單獨查詢,FY.CURRENT_DT將以毫秒爲單位。 – diaryfolio

+0

您是否看過訪問計劃?它說什麼? – AngocA

回答

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沒有數據日期的幫助,儘管它是一個不重要的小表)。

請注意,您可能仍需要執行其他調整,特別是根據您可能(沒有)的指數。

+0

耶你爲「溝內連接」!!!! – HLGEM

相關問題