我正在处理Oracle 11上的庞然大物查询(约800行),并且占用了昂贵的资源。
这里的主要问题是一个约有1800万行的表mouvement
,我在该表上有30个左联接。
LEFT JOIN mouvement mracct_ad1
ON mracct_ad1.code_portefeuille = t.code_portefeuille
AND mracct_ad1.statut_ligne = 'PROPRE'
AND substr(mracct_ad1.code_valeur,1,4) = 'MRAC'
AND mracct_ad1.code_transaction = t.code_transaction
LEFT JOIN mouvement mracct_zias
ON mracct_zias.code_portefeuille = t.code_portefeuille
AND mracct_zias.statut_ligne = 'PROPRE'
AND substr(mracct_zias.code_valeur,1,4) = 'PRAC'
AND mracct_zias.code_transaction = t.code_transaction
LEFT JOIN mouvement mracct_zixs
ON mracct_zias.code_portefeuille = t.code_portefeuille
AND mracct_zias.statut_ligne = 'XROPRE'
AND substr(mracct_zias.code_valeur,1,4) = 'MRAT'
AND mracct_zias.code_transaction = t.code_transaction
是否有某种方法可以摆脱左联接(工会联接或示例),以使查询更快,消耗更少?执行计划之类的?
答案 0 :(得分:2)
只是有关性能的注释。通常,您想“改写”以下条件:
AND substr(mracct_ad1.code_valeur,1,4) = 'MRAC'
简单来说,等式左侧的表达式将阻止索引的最佳使用,并且可能会将SQL优化器推向一个不太理想的计划。数据库引擎最终将完成比实际需要更多的工作,并且查询将慢得多。在极端情况下,他们甚至可以决定使用全表扫描。在这种情况下,您可以将其改写为:
AND mracct_ad1.code_valeur like 'MRAC%'
或:
AND mracct_ad1.code_valeur >= 'MRAC' AND mracct_ad1.code_valeur < 'MRAD'
答案 1 :(得分:0)
我猜是这样。您的代码示例没有多大意义,但您可以进行条件聚合:
left join
(select m.code_portefeuille, m.code_transaction,
max(case when m.statut_ligne = 'PROPRE' and m.code_valeur like 'MRAC%' then ? end) as ad1,
max(case when m.statut_ligne = 'PROPRE' and m.code_valeur like 'MRAC%' then ? end) as zia,
. . . -- for all the rest of the joins as well
from mouvement m
group by m.code_portefeuille, m.code_transaction
) m
on m.code_portefeuille = t.code_portefeuille and m.code_transaction = t.code_transaction
您可能可以将所有30个联接替换为对汇总表的单个联接。