简体   繁体   English

Oracle SQL“复杂”分组查询优化

[英]Oracle SQL “complex” group by query optimization

I have an Oracle Report (10g) where i created several graphs. 我有一个Oracle报告(10g),在其中创建了一些图形。

Now i use two statements like the following in this report. 现在,在此报告中,我使用两个如下语句。 I feel like i had to use two sub-selects in order to get all information the way i want it. 我觉得我必须使用两个子选择才能以我想要的方式获取所有信息。 But the report now uses 7min to generate and i'm wondering if there's anyway to optimize this query 但是该报告现在使用7分钟来生成,我想知道是否有优化该查询的方法

SELECT quantity ,
  commodity ,
  TO_CHAR(quantity,'9999999990.000') string_quantity
FROM
  (SELECT SUM(quantity) quantity ,
    commodity
  FROM
    (SELECT vtr.quant_p quantity,
      DECODE(vtr.commo_num,'CU','CU,MS,PB','MS','CU,MS,PB','PB','CU,MS,PB',vtr.commo_num) commodity
    FROM v_transactions_postp vtr
    WHERE vtr.compa_num = :P_COMPA_NUM
    AND vtr.customer    = :P_CUSTOMER
    AND vtr.POSTPERIOD BETWEEN :P_PP_START AND :P_PP_END
    )
  GROUP BY commodity
  )
ORDER BY quantity DESC

First, you don't need all the subqueries. 首先,您不需要所有子查询。 And CASE is preferable to DECODE() , especially in this case where it simplifies the code: CASEDECODE()更可取,尤其是在这种情况下,它简化了代码:

SELECT SUM(vtr.quant_p) as quantity,  
       (CASE WHEN vtr.commo_num IN ('CU', 'MS', 'PB') THEN 'CU,MS,PB'
             ELSE vtr.commo_num
        END) as commodity
       TO_CHAR(SUM(vtr.quant_p),'9999999990.000') as string_quantity
FROM v_transactions_postp vtr
WHERE vtr.compa_num = :P_COMPA_NUM AND
      vtr.customer    = :P_CUSTOMER AND
      vtr.POSTPERIOD BETWEEN :P_PP_START AND :P_PP_END
GROUP BY (CASE WHEN vtr.commo_num IN ('CU', 'MS', 'PB') THEN 'CU,MS,PB'
               ELSE vtr.commo_num
          END)
ORDER BY SUM(vtr.quant_p) DESC

Then, for performance, you want an index on v_transactions_postp(compa_num, customer, postperiod) . 然后,为了提高性能,您需要在v_transactions_postp(compa_num, customer, postperiod)v_transactions_postp(compa_num, customer, postperiod)索引。 However, I suspect that the "v_" means "view". 但是,我怀疑“ v_”表示“视图”。 That can make the query harder to optimize. 这会使查询更难优化。 You would need the appropriate index on the underlying tables -- or to expand the view in the query. 您将需要在基础表上使用适当的索引-或在查询中扩展视图。

Try below query: 请尝试以下查询:

SELECT sum(vtr.quant_p) quantity,
 (CASE WHEN vtr.commo_num IN ('CU','MS','PB') THEN 'CU,MS,PB' ELSE vtr.commo_num) commodity,
 TO_CHAR(sum(vtr.quant_p), '9999999990.000') string_quantity
 FROM v_transactions_postp vtr
   WHERE vtr.compa_num = :P_COMPA_NUM
     AND vtr.customer = :P_CUSTOMER
     AND vtr.POSTPERIOD BETWEEN :P_PP_START AND :P_PP_END
     GROUP BY commodity
     ORDER BY quantity DESC;

I would suggest you avoid using TO_CHAR in query just to format it in decimal format. 我建议您避免在查询中使用TO_CHAR只是将其设置为十进制格式。 You can get quantity and then add formation logic in your code, say in JAVA or PHP. 您可以获取数量,然后在代码中添加构造逻辑,例如使用JAVA或PHP。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM