代码之家  ›  专栏  ›  技术社区  ›  ZSchneidi

Oracle mutliple左外部仅连接max()行

  •  0
  • ZSchneidi  · 技术社区  · 7 年前

    我有一个经常被安静地使用的语句,但它的表现相当糟糕。 所以我想尽可能地优化它。该声明由多个部分和联合体组成。

    下面是一个相当昂贵的部分。

    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)。

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

    你们有什么建议吗?

    2 回复  |  直到 7 年前
        1
  •  1
  •   eaolson    7 年前

    不可能优化SQL语句 . Oracle将接受您的查询并确定一个执行计划,该计划用于确定您所要求的信息。您可以完全重写查询,如果它导致相同的执行计划,您将获得完全相同的性能。要优化查询,您需要确定 execution plan

    您可能会从这些表中的每个表上的索引中受益 (fi_nr, fklz) 纵列,甚至可能 (fi_nr, fklz, lfdnr) ,这取决于它的选择性。没有办法从这些信息中提前判断,你只需尝试一下。

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

        2
  •  0
  •   Stefanos Zilellis    7 年前

    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 rc0531 inner join 
        (SELECT fi_nr, fklz, MAX(lfdnr) lfdnr FROM rc0531 group by fi_nr, fklz)x on x.fi_nr=rc0531.fi_nr and x.fklz=rc0531.fklz and x.lfdnr=rc0531.lfdnr
    
        ) SUB_TABLE1
      ON F.fklz   = SUB_TABLE1.fklz
      AND F.fi_nr = SUB_TABLE1.fi_nr
    

    如果达到0.1秒,请告诉我,我想它会消失