[英]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: 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
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.