首页 > 解决方案 > Oracle 多左外连接仅 max() 行

问题描述

我有一个经常使用安静但性能很差的语句。所以我想尽可能地优化它。该语句由各个部分和联合组成。

以下是相当昂贵的一部分。

select * 
from rc050 F
LEFT OUTER JOIN
    (SELECT fi_nr,
      fklz,
      rvc_status,
      lfdnr,
      txt
    FROM rc0531 temp
    WHERE lfdnr =
      (SELECT MAX(lfdnr) FROM rc0531 WHERE fi_nr = temp.fi_nr AND fklz = temp.fklz
      )
    ) SUB_TABLE1
  ON F.fklz   = SUB_TABLE1.fklz
  AND F.fi_nr = SUB_TABLE1.fi_nr
LEFT OUTER JOIN
    (SELECT fi_nr,
      fklz,
      rvc_status,
      lfdnr,
      txt
    FROM rc0532 temp
    WHERE lfdnr =
      (SELECT MAX(lfdnr) FROM rc0532 WHERE fi_nr = temp.fi_nr AND fklz = temp.fklz
      )
    ) SUB_TABLE2
  ON F.fklz   = SUB_TABLE2.fklz
  AND F.fi_nr = SUB_TABLE2.fi_nr
LEFT OUTER JOIN
    (SELECT fi_nr,
      fklz,
      rvc_status,
      lfdnr,
      txt
    FROM rc05311 temp
    WHERE lfdnr =
      (SELECT MAX(lfdnr)
      FROM rc05311
      WHERE fi_nr = temp.fi_nr
      AND fklz    = temp.fklz
      )
    ) SUB_TABLE11
  ON F.fklz   = SUB_TABLE11.fklz
  AND F.fi_nr = SUB_TABLE11.fi_nr
where F.fklz != ' '

这是我必须从这些 rc0531 ... rc05311 表中加载最新条目的部分。这些表中有 11 个,因此将其分解。如您所见,我目前正在通过子查询加入每个表,并且只需要最新条目,因此我需要一个额外的子查询来获取 max(lfdnr)。

到目前为止,这一切都很好,但我想知道是否有更有效的方法来执行此操作。

在我的主要选择中,我需要能够处理每个表中的每一列。

你们有什么建议吗?

这目前在 13k 行上运行 1.3 秒以获得不错的提升,这应该下降到 0.1 秒左右。同样,这只是一个充满低效声明的更大声明中的一个问题。

标签: oraclejoinoptimizationsubquerymax

解决方案


无法优化 SQL查询。Oracle 将接受您的查询并确定一个执行计划,用于确定您所要求的信息。您可能会完全重写查询,如果它导致相同的执行计划,您将获得完全相同的性能。要调整查询,您需要确定执行计划

(fi_nr, fklz)您可能会从每个表、列甚至可能的索引中受益(fi_nr, fklz, lfdnr),具体取决于它的选择性。无法从这些信息中提前判断,您只需要尝试即可。

您还应该删除select *并仅选择您想要的列。如果可以从索引中获取所需的信息,Oracle 将不需要检索实际的表行。


推荐阅读