Reputation: 4562
I was facing a performance issue while executing following query.Takes too much time to fetch the results.It was fetching whole results(say 3000)at a time.I was trying to fetch 10 records by using rownum <11
. But it is showing only 3-4 records.Duplicate header_ids
are present.Can we use DISTINCT and rownum here to get 10 rows. Is there any other way to solve this issue??
SELECT DISTINCT oh.header_id,
oh.cust_po_number purchase_order,
oh.order_number,
DECODE(oh.orig_sys_document_ref, NULL, oh.orig_sys_document_ref, SUBSTR(oh.orig_sys_document_ref, LENGTH('OE_ORDER_HEADERS_ALL')+1)) web_reference_number,
TO_CHAR(oh.ordered_date, 'FMMon-DD-YYYY') date_ordered,
(SELECT MIN(schedule_ship_date)
FROM oe_order_lines_all
WHERE header_id = oh.header_id
And Oh.Sold_To_Org_Id = 12338
) oldest_schedule_ship_date,
oe_totals_grp.get_order_total(ol.header_id,NULL,'ALL') total_value,
oh.transactional_curr_code currency_code,
COUNT(*) over() AS total_count
FROM oe_order_headers_all oh,
oe_order_lines_all ol
Where Oh.Header_Id = Ol.Header_Id
-- AND ol.actual_shipment_date BETWEEN sysdate - 180 AND sysdate
AND oh.sold_to_org_id = 12338
Upvotes: 0
Views: 1329
Reputation: 1269923
If you are using rownum
, then I presume you are using Oracle.
Oracle does the distinct
after applying rownum
rather than before. Alas. I think this is part of the same logic where order by
is applied afterwards as well.
You can fix it by using a subquery:
select s.*
from (<your query here>) s
where rownum < 11;
Part of your performance problem may be due to the subquery in the select
. I think you can replace it with an analytic function:
SELECT DISTINCT oh.header_id,
oh.cust_po_number purchase_order, oh.order_number,
DECODE(oh.orig_sys_document_ref, NULL, oh.orig_sys_document_ref,
SUBSTR(oh.orig_sys_document_ref, LENGTH('OE_ORDER_HEADERS_ALL')+1)) web_reference_number,
TO_CHAR(oh.ordered_date, 'FMMon-DD-YYYY') date_ordered,
min(schedule_ship_date) over (partition by oh.header_id) as oldest_schedule_ship_date,
oe_totals_grp.get_order_total(ol.header_id,NULL,'ALL') total_value,
oh.transactional_curr_code currency_code,
COUNT(*) over() AS total_count
FROM oe_order_headers_all oh join
oe_order_lines_all ol
on Oh.Header_Id = Ol.Header_Id
-- AND ol.actual_shipment_date BETWEEN sysdate - 180 AND sysdate where oh.sold_to_org_id = 12338
Actually, to me, it looks like the whole query should be written using group by
rather than distinct
with analytic functions. That might help the performance as well.
Upvotes: 3