在同一个表上具有多个连接的 Oracle 复杂查询
Posted
技术标签:
【中文标题】在同一个表上具有多个连接的 Oracle 复杂查询【英文标题】:Oracle complex query with multiple joins on same table 【发布时间】:2018-08-10 16:45:36 【问题描述】:我正在处理 oracle 11 上的怪物查询(约 800 行),它占用了昂贵的资源。
这里的主要问题是一个表 mouvement
大约有 1800 万行,我在这个表上有 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
有什么方法可以让我摆脱左连接(联合连接或示例)以使查询更快并减少消耗?执行计划什么的?
【问题讨论】:
这几行代码做的事情完全一样。 请解释这两个连接之间除了移动表的别名之外还有什么不同。 对不起,我更新了代码。 【参考方案1】:只是关于性能的说明。通常你想“改写”这样的条件:
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'
【讨论】:
第二个是有风险的,因为NLS_SORT
,不是吗?
@Matthew 是的,我同意你的看法。尽管第二个仍然是一个选项,但我倾向于避免它,因为在使用非典型排序规则时它可能容易出错。
虽然是个好主意,但用like
替换substr()
似乎不太可能对具有30 个左连接的查询产生明显影响。【参考方案2】:
我猜是的。您的代码示例没有多大意义,但您可能可以进行条件聚合:
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 个连接替换为聚合表的单个连接。
【讨论】:
好吧。它只是具有不同值的相同连接。 @mouadtk 。 . .不,这用单个连接替换了一堆不同的连接到聚合结果。在这一点上,我的答案更清楚了。以上是关于在同一个表上具有多个连接的 Oracle 复杂查询的主要内容,如果未能解决你的问题,请参考以下文章