Я испытываю очень странное представление на 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
Интересно, я никогда раньше не писал запрос в этом формате. Попробуйте это сейчас, но, похоже, некоторые ошибки, посмотрим, смогу ли я это понять. Звучит, как планировщик, запутывается! Правильно ли я считаю, что объединение в том, где не существует, должно выполняться как designeD? – CallCthulhu
'WITH' вводит CTE (общие выражения таблицы), которые похожи на временные виды. какие ошибки вы получаете? Что касается путаницы: планировщик на самом деле правильный, и меня это смутило: в SQL, A AND B точно так же, как B AND A (в отличие от большинства языков программирования с коротким замыканием). –