【发布时间】:2020-06-19 05:14:39
【问题描述】:
我有一个每月执行一次的 oracle 查询来处理订单详细信息。这个查询需要花费大量时间来执行。 (超过三十分钟)。因此,我正在尝试对此进行优化。我对甲骨文有相当的了解,我将解释我到目前为止所做的尝试。不过,完成大约需要 20 分钟。这是查询。 Oracle 版本是 11g。
SELECT store_typ, store_no, COUNT(order_no) FROM
(
SELECT DISTINCT(order_no), store.store_no, store.store_typ FROM
(
SELECT trx.order_no,trx.ADDED_DATE, odr.prod_typ, odr.store_no FROM daily_trx trx
LEFT OUTER JOIN
(
SELECT odr.order_no,odr.prod_typ,prod.store_no FROM order_main odr
LEFT OUTER JOIN ORDR_PROD_TYP prod
on odr.prod_typ = prod.prod_typ
) odr
ON trx.order_no= odr.order_no
) daily_orders ,
(SELECT store_no,store_typ FROM main_stores ) store
WHERE 1=1
and daily_orders.order_no !='NA'
and store.store_no = daily_orders.store_no
AND to_timestamp(to_char(daily_orders.ADDED_DATE,'DD-MM-YYYY HH24:MI:SS'),'DD-MM-YYYY HH24:MI:SS') >= to_date('01-05-2020 00:00:00','DD-MM-YYYY HH24:MI:SS')
AND to_timestamp(to_char(daily_orders.ADDED_DATE,'DD-MM-YYYY HH24:MI:SS'),'DD-MM-YYYY HH24:MI:SS') <= to_date('31-05-2020 23:59:59','DD-MM-YYYY HH24:MI:SS')
)
GROUP BY store_typ, store_no
背景
- order_main - 此表有超过 400 万条记录
- 我为 order_no 列引入了索引,减少了执行时间。
我的问题如下。
1) 如果我像这样在内部查询中移动日期验证会有帮助吗?
SELECT store_typ, store_no, COUNT(order_no) FROM
(
SELECT DISTINCT(order_no), store.store_no, store.store_typ FROM
(
SELECT trx.order_no,trx.ADDED_DATE, odr.prod_typ, odr.store_no FROM daily_trx trx
LEFT OUTER JOIN
(
SELECT odr.order_no,odr.prod_typ,prod.store_no FROM order_main odr
LEFT OUTER JOIN ORDR_PROD_TYP prod
on odr.prod_typ = prod.prod_typ
) odr
ON trx.order_no= odr.order_no
WHERE to_timestamp(to_char(daily_orders.ADDED_DATE,'DD-MM-YYYY HH24:MI:SS'),'DD-MM-YYYY HH24:MI:SS') >= to_date('01-05-2020 00:00:00','DD-MM-YYYY HH24:MI:SS')
AND to_timestamp(to_char(daily_orders.ADDED_DATE,'DD-MM-YYYY HH24:MI:SS'),'DD-MM-YYYY HH24:MI:SS') <= to_date('31-05-2020 23:59:59','DD-MM-YYYY HH24:MI:SS')
) daily_orders ,
(SELECT store_no,store_typ FROM main_stores ) store
WHERE 1=1
and daily_orders.order_no !='NA'
and store.store_no = daily_orders.store_no
--AND to_timestamp(to_char(daily_orders.ADDED_DATE,'DD-MM-YYYY HH24:MI:SS'),'DD-MM-YYYY HH24:MI:SS') >= to_date('01-05-2020 00:00:00','DD-MM-YYYY HH24:MI:SS')
--AND to_timestamp(to_char(daily_orders.ADDED_DATE,'DD-MM-YYYY HH24:MI:SS'),'DD-MM-YYYY HH24:MI:SS') <= to_date('31-05-2020 23:59:59','DD-MM-YYYY HH24:MI:SS')
)
GROUP BY store_typ, store_no
2) 有人可以建议对此查询进行的任何其他改进吗?
3) 额外的索引将有助于任何其他表/列?只有daily_trx 和order_main 表是包含大量数据的表。
【问题讨论】:
-
ADDED_DATE是日期数据类型列。应该直接在where条件下使用,不要转成char和timestamp -
请 1) 决定是否要使用 ANSI 连接或 Oracle 连接语法,但不要将它们结合起来。 2) 删除 irrelevant
1=1 AND和 3) 提供有关 所有 表和 执行计划 的信息 - 你可能会发现一些提示 here -
DISTINCT(order_no)?您知道DISTINCT不是在单个列上调用的函数,而是占整行的关键字?DISTINCT通常是次优查询的指标。为什么你首先得到重复?请告诉我们这些表的唯一键是什么。 -
如前所述,我们必须知道表的键才能给出合理的答案。如果您描述了每个表格代表的内容以及您想要计算的内容,这可能会有所帮助。一个订单是指一家商店还是可以指多家商店?您是否只是想计算每家商店在 6 月份至少有一笔交易的订单数?
标签: oracle indexing query-optimization