Hi All,
I am using oracle 8.1.7,solaris 2.8.
I have this query which is taking 3 min for execution.
SELECT COUNT(*) FROM CART_STATS WHERE COMPANY_ID = 8170926 AND ( ((SHIPMENT_STATUS = 'N' or PAYMENT_CLEARED = 'N')
and ARCHIVE != 'D' and STATUS != 'D' and STATUS != 'X' and NUM_TRANSACTIONS > 0) OR ((((SHIPMENT_STATUS = 'Y'
and PAYMENT_CLEARED = 'Y' and STATUS != 'D') OR (STATUS = 'X')) and ARCHIVE != 'D')
and NUM_TRANSACTIONS > 0 and DATE_MODIFIED >= (sysdate - 60)) )
and the execution plan is
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=283 Card=1 Bytes=25)
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'CART_STATS' (Cost=283 Card=1
29 Bytes=3225)
3 2 INDEX (RANGE SCAN) OF 'CART_PS_IDX' (NON-UNIQUE) (Cost
=5 Card=129)
Its using the index which is built on the following columns(composite index)
Hi,
TO tune the query, first of all you can use count(1) INSTEAD of count(*). Secondly create an index on company_id and analyze the table.
I hope this should work. Such heavy composite indexes are usually useless and moreover cause contention than actually help. Try to giving hint /*+INDEX(table_name the index on company_id) */ and try running the query and see if the response time has reduced.
Thanks
So, there are a lot of rows . . . all 54'712 have to be read from the table - that could be enough to explain 3 minutes if most are not in buffers (depends on your hardware - I make that 3ms/row).
(check my logic here) I think you can rewrite the query as
Code:
SELECT COUNT(*)
FROM CART_STATS
WHERE COMPANY_ID = 8170926
and ARCHIVE != 'D'
and NUM_TRANSACTIONS > 0
and
(
(LOTS OF STUFF)
OR
(LOTS OF STUFF)
)
in which case an index on (COMPANY_ID, ARCHIVE, NUM_TRANSACTIONS) could be useful if these extra columns are selective.
So how many rows from:
SELECT COUNT(*)
FROM CART_STATS
WHERE COMPANY_ID = 8170926
and ARCHIVE != 'D'
and NUM_TRANSACTIONS > 0
Bookmarks