My Oracle SQL query is given below -
Q1-
select
hca.account_number,
hca.attribute3,
SUM(rcl.extended_amount)
from
ra_customer_trx_all rct
JOIN ra_customer_trx_lines_all rcl
ON rct.customer_trx_id = rcl.customer_trx_id
JOIN HZ_CUST_ACCOUNTS_ALL hca
ON rct.bill_to_customer_id = hca.cust_account_id
where
rct.trx_date >= TO_DATE('01-MAR-2020', 'DD-MON-YYYY')
AND
rct.trx_date < TO_DATE('03-MAR-2020', 'DD-MON-YYYY')
AND
rcl.line_type = 'LINE'
AND
rct.org_id = 3523
AND hca.account_number = '1063431'
group by
hca.account_number,
hca.attribute3;
It seems pretty straight-forward but I cannot seem to understand why the above query runs a lot slower as compared to the exact same version of the query except I comment out the last where statement -
Q2 -
select
hca.account_number,
hca.attribute3,
SUM(rcl.extended_amount)
from
ra_customer_trx_all rct
JOIN ra_customer_trx_lines_all rcl
ON rct.customer_trx_id = rcl.customer_trx_id
JOIN HZ_CUST_ACCOUNTS_ALL hca
ON rct.bill_to_customer_id = hca.cust_account_id
where
rct.trx_date >= TO_DATE('01-MAR-2020', 'DD-MON-YYYY')
AND
rct.trx_date < TO_DATE('03-MAR-2020', 'DD-MON-YYYY')
AND
rcl.line_type = 'LINE'
AND
rct.org_id = 3523
-- AND hca.account_number = '1063431' ***THIS IS NOW COMMENTED***
group by
hca.account_number,
hca.attribute3;
Q1 takes about 20 minutes whereas Q2 runs in 1 second.
I'm not really good at query tuning, but I have an index on account_number, made sure there's no implicit datatype conversions. The explain plan tells me the where clause would use a Index Unique Scan which I believe is the correct option. I would have assumed that adding a where clause should make it faster, as you are narrowing down the number of rows to be grouped. But it seems my assumption is incorrect, as I am observing the complete opposite of what I had assumed.
Explain plans given below -
Q1 (With Where Clause)
-----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 245 (100)| |
| 1 | HASH GROUP BY | | 1 | 53 | 245 (1)| 00:00:01 |
| 2 | NESTED LOOPS | | | | | |
| 3 | NESTED LOOPS | | 1 | 53 | 245 (1)| 00:00:01 |
| 4 | NESTED LOOPS | | 1 | 38 | 240 (1)| 00:00:01 |
| 5 | TABLE ACCESS BY INDEX ROWID| HZ_CUST_ACCOUNTS | 1 | 15 | 2 (0)| 00:00:01 |
|* 6 | INDEX UNIQUE SCAN | HZ_CUST_ACCOUNTS_U2 | 1 | | 1 (0)| 00:00:01 |
|* 7 | TABLE ACCESS BY INDEX ROWID| RA_CUSTOMER_TRX_ALL | 1 | 23 | 238 (1)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | XXCCC_RA_CUSTOMER_TRX_ALL_N97 | 1353 | | 8 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | RA_CUSTOMER_TRX_LINES_N2 | 2 | | 3 (0)| 00:00:01 |
|* 10 | TABLE ACCESS BY INDEX ROWID | RA_CUSTOMER_TRX_LINES_ALL | 1 | 15 | 5 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
6 - access("HCA"."ACCOUNT_NUMBER"='1063431')
7 - filter(("RCT"."TRX_DATE">=TO_DATE(' 2020-03-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
"RCT"."ORG_ID"=3523 AND "RCT"."TRX_DATE"<TO_DATE(' 2020-03-03 00:00:00', 'syyyy-mm-dd hh24:mi:ss')))
8 - access("RCT"."BILL_TO_CUSTOMER_ID"="HCA"."CUST_ACCOUNT_ID")
9 - access("RCT"."CUSTOMER_TRX_ID"="RCL"."CUSTOMER_TRX_ID")
10 - filter("RCL"."LINE_TYPE"='LINE')
Q2 (Without Where Clause)
-----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | | 137K(100)| |
| 1 | HASH GROUP BY | | 43 | 1892 | | 137K (1)| 00:00:11 |
| 2 | NESTED LOOPS | | | | | | |
| 3 | NESTED LOOPS | | 34875 | 1498K| | 137K (1)| 00:00:11 |
| 4 | VIEW | VW_GBF_9 | 29570 | 837K| | 4665 (1)| 00:00:01 |
| 5 | HASH GROUP BY | | 29570 | 1097K| 1400K| 4665 (1)| 00:00:01 |
|* 6 | HASH JOIN | | 29570 | 1097K| | 4369 (1)| 00:00:01 |
|* 7 | TABLE ACCESS BY INDEX ROWID| RA_CUSTOMER_TRX_ALL | 29570 | 664K| | 3904 (1)| 00:00:01 |
|* 8 | INDEX SKIP SCAN | RA_CUSTOMER_TRX_N17 | 33634 | | | 189 (1)| 00:00:01 |
| 9 | TABLE ACCESS FULL | HZ_CUST_ACCOUNTS | 43897 | 643K| | 464 (1)| 00:00:01 |
|* 10 | INDEX RANGE SCAN | RA_CUSTOMER_TRX_LINES_N2 | 2 | | | 3 (0)| 00:00:01 |
|* 11 | TABLE ACCESS BY INDEX ROWID | RA_CUSTOMER_TRX_LINES_ALL | 1 | 15 | | 5 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
6 - access("RCT"."BILL_TO_CUSTOMER_ID"="HCA"."CUST_ACCOUNT_ID")
7 - filter("RCT"."ORG_ID"=3523)
8 - access("RCT"."TRX_DATE">=TO_DATE(' 2020-03-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
"RCT"."TRX_DATE"<TO_DATE(' 2020-03-03 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
filter(("RCT"."TRX_DATE">=TO_DATE(' 2020-03-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
"RCT"."TRX_DATE"<TO_DATE(' 2020-03-03 00:00:00', 'syyyy-mm-dd hh24:mi:ss')))
10 - access("ITEM_1"="RCL"."CUSTOMER_TRX_ID")
11 - filter("RCL"."LINE_TYPE"='LINE')
EDIT: Sorry, added images of execution plans below.