我需要查询订单表以获取昨天交易的所有订单的计数,按发货日期分组。然后我需要一个额外的列来给出所有交易的发货日期的总订单。当我添加第二列时,处理时间呈指数增长(预期为)到109s。有什么办法可以改进这个SQL吗?我只是想知道我是否遗漏了任何根本的东西。
SELECT t.shipping_date
, t.net_orders
, count(*) as total_orders
FROM (
SELECT s.store_num
, s.store_cd
, to_char(o.shipping_date, 'MM/DD/YYYY') as shipping_date
, COUNT (*) as net_orders
FROM order o left
join store s
on ( s.store_num = o.store_num )
WHERE TRUNC (o.order_date) = TRUNC (SYSDATE - 1)
AND s.store_cd = 'ZZZ'
AND o.status in ('A', 'B')
GROUP BY s.store_num
, s.store_cd
, to_char(shipping_date, 'MM/DD/YYYY')
) t
LEFT JOIN order o ON
( TRUNC (o.shipping_date) = to_date(t.shipping_date, 'MM/DD/YYYY')
and o.store_num = t.store_num )
WHERE o.status in ('A', 'B')
GROUP BY t.shipping_date, t.net_orders;
除了以下表达式之外,我在所有这些列上都有索引:TRUNC(order_date)和TRUNC(shipping_date)。
答案 0 :(得分:3)
如果您只是寻找输出:
shipping_date net_orders total_orders
01-AUG-2004 14 37
02-AUG-2004 17 29
03-AUG-2004 19 43
如何:
SELECT *
FROM (
SELECT TRUNC(o.shipping_date) as shipping_date
, COUNT(CASE WHEN TRUNC(o.order_date) = TRUNC(SYSDATE - 1)
THEN 1
ELSE NULL
END) as net_orders -- count does not count NULL values.
, COUNT(*) as total_orders
FROM order o
LEFT JOIN
store s
on s.store_num = o.store_num
WHERE s.store_cd = 'ZZZ'
AND o.status in ('A', 'B')
GROUP BY TRUNC(o.shipping_date)
)
WHERE net_orders > 0 -- only shipping dates that had at least one order yesterday
它可以避免额外的联接回到订单表,因为无论如何你将不得不触摸商店的所有订单,当你获得总数时,你也可以做我所做的事情。 d同时调用条件计数。
答案 1 :(得分:1)
我将您的查询重写为:
SELECT t.shipping_date,
t.net_orders,
COUNT(*) as total_orders
FROM (SELECT s.store_num,
s.store_cd,
o.status,
TRUNC(o.shipping_date) AS shipping_date,
COUNT (*) as net_orders
FROM STORE s
JOIN ORDER o ON o.store_num = s.store_num
AND o.status IN ('A', 'B')
WHERE s.store_cd = 'ZZZ'
AND TRUNC(order_date) = TRUNC (SYSDATE - 1)
GROUP BY s.store_num, s.store_cd, TRUNC(shipping_date)) t
LEFT JOIN ORDER o ON TRUNC(o.shipping_date) = t.shipping_date
AND o.store_num = t.store_num
AND o.status = t.status
GROUP BY t.shipping_date, t.net_orders;
一些小的重新安排,但我确实摆脱了TO_CHAR(shipping_date),后来转换回DATE。 TRUNC(shipping_date)
是相同的,并简化了操作。
使用函数加入条件不会使用索引 - 您需要创建一个与JOIN条件匹配的基于函数的索引。