I need to query the orders table to get a count of all orders for yesterdays transactions, grouped by the ship date. Then I need to have an additional column to give the total orders for the ship date for all transactions. When I added this second column, time of processing grew exponentially (which was expected) to 109s. Is there any way I could improve this SQL? I just want to know if I’m missing anything fundamental here.
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;
I have indexes on all of these columns in addition to the following expressions: TRUNC(order_date) and TRUNC(shipping_date).
I re-wrote your query as:
Some minor re-arrangement, but I did get rid of the TO_CHAR(shipping_date) which is later converted back to a DATE.
TRUNC(shipping_date)is the same, and simplifies the operation.Joining on criteria using functions won’t use an index – you’ll need to create a function based index matching the JOIN criteria.