【问题标题】:Query optimization [Oracle]查询优化 [Oracle]
【发布时间】:2018-12-05 14:56:31
【问题描述】:

如何优化此查询的性能?

SELECT Count(DISTINCT DT.id) 
FROM   pcwdeptrans DT 
       INNER JOIN pcwitemtotal IT 
               ON DT.id = IT.deposittransid 
       LEFT OUTER JOIN pcwdepreceipt DR 
                    ON DR.deposittransid = DT.id 
WHERE  (( ( DT.statecode IN ( :1, :2, :3, :4, 
                              :5, :6, :7, :8 ) 
             OR ( DT.statecode IN ( :9 ) 
                  AND IT.statecode = :10 ) ) 
          AND DR.requesttime >= :11 
          AND DR.requesttime <= :12 
          AND DR.userid = :13 )) 

如果您认为语法不正确,请帮助我正确的语法。

但这是一个应用程序查询,从 AWR 报告中识别为性能分析的一部分

摘自 AWR:

Top SQL with TOP Events

来自测试数据库的执行计划(产品会有所不同):

Execution plan of the query

【问题讨论】:

  • 您的WHERE 子句正在将外连接变成内连接——如果我没看错括号的话。
  • 我同意戈登的观点。在开始调整之前,您应该确保您的查询功能正确

标签: sql oracle performance sql-tuning


【解决方案1】:

与 Where 一起加入可能会很慢。以下可能会更快(但不一样...请参阅 cmets 并重新考虑是否需要内部或外部联接...)

SELECT Count(DISTINCT DT.id) 
FROM pcwdeptrans DT 
  INNER JOIN pcwitemtotal IT 
      ON DT.id = IT.deposittransid 
     AND ( DT.statecode IN ( :1, :2, :3, :4, :5, :6, :7, :8 ) 
       OR ( DT.statecode IN ( :9 ) AND IT.statecode = :10 ) )
  LEFT OUTER JOIN pcwdepreceipt DR 
      ON DR.deposittransid = DT.id 
     AND DR.requesttime >= :11 
     AND DR.requesttime <= :12 
     AND DR.userid = :13

编辑: 之前在问题的 cmets 中已经开始讨论是内连接还是外连接。使用 where 子句将问题的外连接转换为内连接可能是也可能不是有意的。

SELECT Count(DISTINCT DT.id) 
FROM pcwdeptrans DT 
  INNER JOIN pcwitemtotal IT 
      ON DT.id = IT.deposittransid 
     AND ( DT.statecode IN ( :1, :2, :3, :4, :5, :6, :7, :8 ) 
       OR ( DT.statecode IN ( :9 ) AND IT.statecode = :10 ) )
  INNER JOIN pcwdepreceipt DR 
      ON DR.deposittransid = DT.id 
     AND DR.requesttime >= :11 
     AND DR.requesttime <= :12 
     AND DR.userid = :13

【讨论】:

  • 这不会改变查询逻辑吗? WHERE 子句中的过滤有效地使与 pcwdepreceipt 的联接成为 INNER JOIN
猜你喜欢
  • 2015-02-26
  • 2011-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多