2009-11-17 3 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 
) 
; 

Что должно произойти, что запрос обращается к partion 97 из nwhd12.chldr_auths, так как это раздел, соответствующий циклу 200911. Вместо этого, после доступа к разделу 97, он начинает доступ к каждому другому разделу в nwhd12.chldr_auths. Теперь мне сказали, что это из-за «WHERE NOT EXISTS», но в этом утверждении все еще есть ограничение на циклы (a.cycl_num = b.cycl_num), так почему это сканирование всех разделов?

Если я жестко закодирую цикл в том месте, где он не существует, запрос выполняется так, как ожидалось.

Спасибо, Dave

ответ

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

Интересно, я никогда раньше не писал запрос в этом формате. Попробуйте это сейчас, но, похоже, некоторые ошибки, посмотрим, смогу ли я это понять. Звучит, как планировщик, запутывается! Правильно ли я считаю, что объединение в том, где не существует, должно выполняться как designeD? – CallCthulhu

+0

'WITH' вводит CTE (общие выражения таблицы), которые похожи на временные виды. какие ошибки вы получаете? Что касается путаницы: планировщик на самом деле правильный, и меня это смутило: в SQL, A AND B точно так же, как B AND A (в отличие от большинства языков программирования с коротким замыканием). –

Смежные вопросы