Oracle SQL“复杂”组通过查询优化

时间:2017-06-27 08:49:13

标签: sql oracle performance optimization

我有一个Oracle报告(10g),我创建了几个图表。

现在我在本报告中使用如下两个语句。我觉得我必须使用两个子选项才能以我想要的方式获取所有信息。 但该报告现在使用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

2 个答案:

答案 0 :(得分:1)

首先,您不需要所有子查询。 CASE优于DECODE(),尤其是在这种简化代码的情况下:

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

然后,为了提高性能,您需要v_transactions_postp(compa_num, customer, postperiod)上的索引。但是,我怀疑“v_”表示“查看”。这可能会使查询更难以优化。您需要在基础表上使用适当的索引 - 或者在查询中展开视图。

答案 1 :(得分:0)

尝试以下查询:

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;

我建议你不要在查询中使用TO_CHAR,只是以十进制格式格式化它。您可以获取数量,然后在代码中添加编队逻辑,例如JAVA或PHP。