SQL帮助 - 重写查询

时间:2017-12-12 21:42:16

标签: sql oracle performance query-optimization

我们如何减少以下查询的执行时间?

需要帮助以更有效的方式重写SQL查询下面的内容吗?

SELECT A.*, C.*, F.*, D.*
FROM TABLE1 A  INNER JOIN
     TABLE2 C
     ON A.CODE = C.CODE INNER JOIN
     TABLE3 D
     ON A.CODE = D.CODE INNER JOIN
     TABLE4 F
     ON A.CODE = F.CODE
WHERE D.IND1 = 'N' AND
      D.IND2 = 'N' AND
      D.EFF_DATE = (SELECT MAX(X.EFF_DATE)
                    FROM TABLE3 X
                    WHERE X.CODE = D.CODE AND X.EFF_DATE <= A.EFFECTIVE_DATE
                   ) AND
      F.EFF_DATE = (SELECT MAX(Z.EFF_DATE)
                    FROM TABLE4 Z
                    WHERE Z.DETAIL_CODE = F.DETAIL_CODE AND Z.EFF_DATE <= A.EFFECTIVE_DATE
                   )

4 个答案:

答案 0 :(得分:0)

对于性能,我将从索引开始:

  • TABLE3(IND1, IND2, CODE, EFF_DATE)
  • TABLE3(CODE, EFF_DATE)
  • TABLE1(CODE, EFF_DATE)
  • TABLE2(CODE)
  • TABLE4(CODE)
  • TABLE4(DETAIL_CODE, EFF_DATE)

如果您遇到性能问题,我怀疑您的代码可能会产生意外的笛卡尔产品。调试需要更多信息。我可能会建议再问一个问题。

答案 1 :(得分:0)

如果您可以找到查询瓶颈的位置 - 即子查询,联接 - 这将使您更好地了解要查看的内容。如果没有,请看看:

如果您可以提供EXPLAIN计划(或Oracle的等效计划),那将会有所帮助。

答案 2 :(得分:0)

请注意,由于两个子查询的条件,结果中的所有记录都会有D.EFF_DATE <= A.EFFECTIVE_DATEF.EFF_DATE <= A.EFFECTIVE_DATE,因此我建议将这些条件放在JOIN中条款。

其次,分析函数可以提供比子查询更好的性能:

SELECT *
FROM (
  SELECT      A.*,C.*,F.*,D.*,
              RANK() OVER (PARTITION BY D.CODE 
                           ORDER BY D.EFF_DATE DESC) AS D_RANK,
              RANK() OVER (PARTITION BY F.DETAIL_CODE 
                           ORDER BY F.EFF_DATE DESC) AS F_RANK
  FROM        TABLE1 A
  INNER JOIN  TABLE2 C
           ON A.CODE = C.CODE
  INNER JOIN  TABLE3 D
           ON A.CODE = D.CODE
          AND D.EFF_DATE <= A.EFFECTIVE_DATE
  INNER JOIN  TABLE4 F
           ON A.CODE = F.CODE
          AND F.EFF_DATE <= A.EFFECTIVE_DATE
  WHERE       D.IND1 = 'N'
          AND D.IND2 = 'N'
)
WHERE D_RANK = 1 AND F_RANK = 1

显然,您需要拥有正确的索引来优化执行计划。

答案 3 :(得分:0)

要考虑的另一件事是查询返回的列总数,您似乎是从4个表中选择所有列。

我们发现,我们的复杂查询只需选择几列就会在一秒钟内运行,但在选择多列时会花费更长的时间。

问你为什么在结果集中需要这么多列。