2009-11-17 69 views
2

性能運行查詢時,下面我遇到的DB2 9.1版本非常奇怪的表現:奇WHERE NOT EXISTS在DB2

select a.CYCL_NUM 
, a.AC_NUM 
, a.AUTHS_DTE 
, a.PL_ID 
, a.APRVD_RSPN_CDE 
, a.AUTHS_AMT 
, a.AUTHS_STS_CDE 
, a.TRAN_CTGR_CDE 
, a.MRCHN_CTGR_CDE 
, d.out_pu_au_amt 
from nwhd12.chldr_auths a, nwhd12.w_chldr_ac d 
where cycl_num = 200911 
and a.ac_num = d.ac_num 
and APRVD_RSPN_CDE = 'APV' 
and not exists (
    select 1 from auths_rev_hist b 
where a.cycl_num = b.cycl_num 
     and a.auths_dte = b.auths_dte 
     and a.TRAN_CTGR_CDE = b.TRAN_CTGR_CDE 
     and a.PL_ID = b.pl_id 
     and a.APRVD_RSPN_CDE = b.APRVD_RSPN_CDE 
and a.AUTHS_AMT = b.auths_amt 
     and a.TRAN_CTGR_CDE = b.TRAN_CTGR_CDE 
     and a.MRCHN_CTGR_CDE = MRCHN_CTGR_CDE 
) 
; 

什麼是應該發生的是,查詢訪問nwhd12.chldr_auths的partion 97,因爲這是與循環200911相對應的分區。相反,在訪問分區97之後,它開始訪問nwhd12.chldr_auths中的每個其他分區。現在,我被告知這是因爲「WHERE NOT EXISTS」,但是這個語句中的循環仍然存在限制(a.cycl_num = b.cycl_num),所以爲什麼要掃描所有分區?

如果我在不存在的地方硬編碼循環,那麼查詢按預期執行。

謝謝, 戴夫

回答

2

如果規劃者是這樣的容易混淆的,你需要嘗試一些不同的配方。這未經測試(我甚至沒有DB2,但CTE起源於那裏):

WITH hist AS (
    cycl_num 
    , ac_num 
    , auths_dte 
    , pl_id 
    , aprvd_rspn_cde 
    , auths_amt 
    , auths_sts_cde 
    , tran_ctgr_cde 
    , mrchn_ctgr_cde 
    FROM auths_rev_hist b 
) 
, auths AS (
    SELECT 
    cycl_num 
    , ac_num 
    , auths_dte 
    , pl_id 
    , aprvd_rspn_cde 
    , auths_amt 
    , auths_sts_cde 
    , tran_ctgr_cde 
    , mrchn_ctgr_cde 
    FROM nwhd12.chldr_auths 
    WHERE cycl_num = 200911 
    AND aprvd_rspn_cde = 'APV' 
    EXCEPT 
    SELECT ... FROM hist 
) 
SELECT a.*, d.out_pu_au_amt 
FROM auths a, nwhd12.w_chldr_ac d 
WHERE a.ac_num = d.ac_num 
+0

有趣的是,我從來沒有寫過這種格式的查詢。現在試試看,但似乎有一些錯誤,會看看我能否弄清楚。聽起來就像計劃者感到困惑!我是否認爲加入不存在的地方應該像設計師那樣表現? – CallCthulhu 2009-11-17 05:42:29

+0

WITH WITH引入了CTE(通用表格表達式),就像臨時視圖。你得到什麼錯誤?關於混淆: 關於這個混淆:規劃者實際上是正確的,而我卻感到困惑:在SQL中,A AND B與B AND A完全相同(與大多數帶短路的編程語言相反)。 – 2009-11-17 05:55:52