Oracle LEFT JOIN View performance - performance

I have two tables, they aren't large tables.
I have created a View based on this tables
select
tab_a.id as id,
tab_a.name as name
from tableA as tab_a
UNION ALL
select
tab_b.id as id,
tab_b.name as name
from tableB as tab_b
After all, I have a third table, lets call it tableMain with fields:
tableMain.id, tableMain.status, tableMain.viewId
viewId exists to join view
Final select look like
SELECT tableMain.id
FROM tableMain
LEFT OUTER JOIN VIEW ON tableMain.viewId=view.id
and join is very slow on a VIEW.
its fast if I join directly tableA or tableB, but not when using view.
It could be fast if I use view.name in select
SELECT tableMain.id, VIEW.name
FROM tableMain
LEFT OUTER JOIN VIEW ON tableMain.viewId=view.id
Not sure why VIEW JOIN working fast if I use VIEW field in select,
and how make VIEW JOIN fast without it.
Posting plans:
Good Plan (using VIEW.name in SELECT)
SELECT tableMain.id, VIEW.name
FROM tableMain
LEFT OUTER JOIN VIEW ON tableMain.viewId=view.id
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 220K| 440M| 50 (4)| 00:00:01 |
|* 1 | HASH JOIN OUTER | | 220K| 440M| 50 (4)| 00:00:01 |
| 2 | TABLE ACCESS FULL | **tableMain** | 19796 | 1527K| 42 (0)| 00:00:01 |
| 3 | VIEW | ***VIEW*** | 1115 | 2194K| 6 (0)| 00:00:01 |
| 4 | UNION-ALL | | | | | |
| 5 | TABLE ACCESS FULL| **tableA** | 818 | 1609K| 3 (0)| 00:00:01 |
|* 6 | TABLE ACCESS FULL| **tableB** | 297 | 5346 | 3 (0)| 00:00:01 |
Bad Plan (no view.name in select)
SELECT tableMain.id
FROM tableMain
LEFT OUTER JOIN VIEW ON tableMain.viewId=view.id
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
| 0 | SELECT STATEMENT | | 220K| 19M| 51 (6)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10003 | 220K| 19M| 51 (6)| 00:00:01 | Q1,03 | P->S | QC (RAND) |
|* 3 | HASH JOIN RIGHT OUTER | | 220K| 19M| 51 (6)| 00:00:01 | Q1,03 | PCWP | |
| 4 | PX RECEIVE | | 1115 | 14495 | 6 (0)| 00:00:01 | Q1,03 | PCWP | |
| 5 | PX SEND HASH | :TQ10002 | 1115 | 14495 | 6 (0)| 00:00:01 | Q1,02 | P->P | HASH |
| 6 | BUFFER SORT | | 220K| 19M| | | Q1,02 | PCWP | |
| 7 | VIEW | ***VIEW*** | 1115 | 14495 | 6 (0)| 00:00:01 | Q1,02 | PCWP | |
| 8 | UNION-ALL | | | | | | Q1,02 | PCWP | |
| 9 | PX BLOCK ITERATOR | | 818 | 10634 | 3 (0)| 00:00:01 | Q1,02 | PCWC | |
| 10 | INDEX FAST FULL SCAN| ***tableA_PK*** | 818 | 10634 | 3 (0)| 00:00:01 | Q1,02 | PCWP | |
| 11 | BUFFER SORT | | | | | | Q1,02 | PCWC | |
| 12 | PX RECEIVE | | 297 | 2079 | 3 (0)| 00:00:01 | Q1,02 | PCWP | |
| 13 | PX SEND ROUND-ROBIN| :TQ10000 | 297 | 2079 | 3 (0)| 00:00:01 | | S->P | RND-ROBIN |
|* 14 | TABLE ACCESS FULL | **tableB** | 297 | 2079 | 3 (0)| 00:00:01 | | | |
| 15 | BUFFER SORT | | | | | | Q1,03 | PCWC | |
| 16 | PX RECEIVE | | 19796 | 1527K| 42 (0)| 00:00:01 | Q1,03 | PCWP | |
| 17 | PX SEND HASH | :TQ10001 | 19796 | 1527K| 42 (0)| 00:00:01 | | S->P | HASH |
| 18 | TABLE ACCESS FULL | **tableMain** | 19796 | 1527K| 42 (0)| 00:00:01 | | | |
Why so big difference?

Something is forcing parallelism. Does the view have any hints? Is there some type of plan management happening with this query? For example, is there an outline, SQL Plan Management, or profile setup only on the bad query? You may be able to find out by adding
the Note section of the explain plan. If I'm right, there will be something like this in only one of the execution plans:
Note
-----
- SQL plan baseline "SQL_PLAN_01yu884fpund494ecae5c" used FOR this statement
Also it would help to define "very slow". If the good query runs in 0.01 seconds and the bad query runs in 2 seconds, the difference may be all because of the overhead of
parallelism. But if the query was tuned for an environment with much larger data you may want to keep that the bad plan anyway - it may run better in production.

Related

Oracle first N rows of a group using RANK running too slow

I have a table with below columns
Table{
load_date DATE
effective_date DATE
Application_ID Varchar2
Datasource_id VARCHAR2
Rule_id Varchar2
Entity_Id varchar2
Rule_status number
batch_execution_ts TIMESTAMP
}
Now I have a query to fetch results as below
select * from (
select rank() over (partition by effective_date, rule_id, entity_id order by batch_execution_ts desc) as rank,
s.*
from TABLE s
where s.load_date between :date1 and :date2
and s.effective_date between :effdate1 and :effdate2
and application_id=:appid
and datasource_id=:dsid) result
where result.rank=1
We have a query requirement to send results in max od 3seconds.. but this query is running for whopping 4 mins and no results returned. TABLE is partitioned on "load_date"and we have LOCAL INDEX created on effective_date, application_id, datasource_id, rule_id, entity_id
Any suggestion on improving performance. FYI.. each load_date partition contains around 2-3 million rows. Running parallel is not helping the performance either.
Added EXPLAIN PLAN below.
Plan hash value: 2095006046
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 8 | 20720 | 425 (1)| 00:00:01 | | | | | |
|* 1 | PX COORDINATOR | | | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10001 | 8 | 20720 | 425 (1)| 00:00:01 | | | Q1,01 | P->S | QC (RAND) |
|* 3 | VIEW | | 8 | 20720 | 425 (1)| 00:00:01 | | | Q1,01 | PCWP | |
|* 4 | WINDOW SORT PUSHED RANK | | 8 | 12776 | 425 (1)| 00:00:01 | | | Q1,01 | PCWP | |
| 5 | PX RECEIVE | | 8 | 12776 | 425 (1)| 00:00:01 | | | Q1,01 | PCWP | |
| 6 | PX SEND HASH | :TQ10000 | 8 | 12776 | 425 (1)| 00:00:01 | | | Q1,00 | P->P | HASH |
|* 7 | WINDOW CHILD PUSHED RANK | | 8 | 12776 | 425 (1)| 00:00:01 | | | Q1,00 | PCWP | |
|* 8 | FILTER | | | | | | | | Q1,00 | PCWC | |
| 9 | NESTED LOOPS OUTER | | 8 | 12776 | 424 (0)| 00:00:01 | | | Q1,00 | PCWP | |
| 10 | PX PARTITION RANGE ITERATOR | | 8 | 2576 | 422 (0)| 00:00:01 | KEY | KEY | Q1,00 | PCWC | |
| 11 | TABLE ACCESS BY LOCAL INDEX ROWID| DQM_ENTITY_RULE_STATUS | 8 | 2576 | 422 (0)| 00:00:01 | KEY | KEY | Q1,00 | PCWP | |
|* 12 | INDEX RANGE SCAN | NU_DQM_ERS_IDX_4 | 27 | | 421 (0)| 00:00:01 | KEY | KEY | Q1,00 | PCWP | |
| 13 | VIEW PUSHED PREDICATE | | 1 | 1275 | 7 (0)| 00:00:01 | | | Q1,00 | PCWP | |
| 14 | NESTED LOOPS OUTER | | 1 | 757 | 7 (0)| 00:00:01 | | | Q1,00 | PCWP | |
| 15 | NESTED LOOPS OUTER | | 1 | 725 | 6 (0)| 00:00:01 | | | Q1,00 | PCWP | |
| 16 | NESTED LOOPS | | 1 | 711 | 5 (0)| 00:00:01 | | | Q1,00 | PCWP | |
| 17 | NESTED LOOPS | | 1 | 614 | 4 (0)| 00:00:01 | | | Q1,00 | PCWP | |
| 18 | NESTED LOOPS | | 1 | 511 | 3 (0)| 00:00:01 | | | Q1,00 | PCWP | |
|* 19 | TABLE ACCESS BY INDEX ROWID | DQM_RULE | 1 | 479 | 2 (0)| 00:00:01 | | | Q1,00 | PCWP | |
|* 20 | INDEX UNIQUE SCAN | PK_DQM_RULE | 1 | | 1 (0)| 00:00:01 | | | Q1,00 | PCWP | |
| 21 | TABLE ACCESS BY INDEX ROWID | DQM_FW_DQ_DIM | 1 | 32 | 1 (0)| 00:00:01 | | | Q1,00 | PCWP | |
|* 22 | INDEX UNIQUE SCAN | PK_DQM_FW_DQ_DIM | 1 | | 0 (0)| 00:00:01 | | | Q1,00 | PCWP | |
| 23 | TABLE ACCESS BY INDEX ROWID | DQM_RULE_FUNCTION | 1 | 103 | 1 (0)| 00:00:01 | | | Q1,00 | PCWP | |
|* 24 | INDEX UNIQUE SCAN | PK_DQM_RULE_FUNCTION | 1 | | 0 (0)| 00:00:01 | | | Q1,00 | PCWP | |
| 25 | TABLE ACCESS BY INDEX ROWID | DQM_RULE_GRP | 1 | 97 | 1 (0)| 00:00:01 | | | Q1,00 | PCWP | |
|* 26 | INDEX UNIQUE SCAN | PK_DQM_RULE_GRP | 1 | | 0 (0)| 00:00:01 | | | Q1,00 | PCWP | |
|* 27 | INDEX FULL SCAN | PK_DQM_FW_DQ_DIM_HRCHY | 1 | 14 | 1 (0)| 00:00:01 | | | Q1,00 | PCWP | |
| 28 | TABLE ACCESS BY INDEX ROWID | DQM_FW_DQ_DIM | 1 | 32 | 1 (0)| 00:00:01 | | | Q1,00 | PCWP | |
|* 29 | INDEX UNIQUE SCAN | PK_DQM_FW_DQ_DIM | 1 | | 0 (0)| 00:00:01 | | | Q1,00 | PCWP | |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TO_DATE(:EFFECTIVEDATETO)>=TO_DATE(:EFFECTIVEDATEFROM) AND TO_DATE(:LOADDATETO)>=TO_DATE(:LOADDATEFROM))
3 - filter("LATEST_EXCEPTION"=1)
4 - filter(RANK() OVER ( PARTITION BY "S"."EFFECTIVE_DT","S"."VENDOR_ENTITY_KEY","S"."RULE_ID" ORDER BY INTERNAL_FUNCTION("S"."BATCH_EXECUTION_TS")
DESC )<=1)
7 - filter(RANK() OVER ( PARTITION BY "S"."EFFECTIVE_DT","S"."VENDOR_ENTITY_KEY","S"."RULE_ID" ORDER BY INTERNAL_FUNCTION("S"."BATCH_EXECUTION_TS")
DESC )<=1)
8 - filter(TO_DATE(:EFFECTIVEDATETO)>=TO_DATE(:EFFECTIVEDATEFROM) AND TO_DATE(:LOADDATETO)>=TO_DATE(:LOADDATEFROM))
12 - access("S"."EFFECTIVE_DT">=:EFFECTIVEDATEFROM AND "S"."LOAD_DT">=:LOADDATEFROM AND "S"."APPLICATION_ID"=SYS_OP_C2C(:SOURCEID) AND
"S"."DATA_SOURCE_ID"=SYS_OP_C2C(:VENDORID) AND "S"."EFFECTIVE_DT"<=:EFFECTIVEDATETO AND "S"."LOAD_DT"<=:LOADDATETO)
filter("S"."LOAD_DT">=:LOADDATEFROM AND "S"."LOAD_DT"<=:LOADDATETO AND "S"."DATA_SOURCE_ID"=SYS_OP_C2C(:VENDORID) AND
"S"."APPLICATION_ID"=SYS_OP_C2C(:SOURCEID))
19 - filter("RULETABLE"."FUNC_ID" IS NOT NULL AND "RULETABLE"."RULE_GRP_ID" IS NOT NULL)
20 - access("RULETABLE"."RULE_ID"="S"."RULE_ID")
22 - access("DIM"."DIMENSION_ID"="RULETABLE"."DIMENSION_ID")
24 - access("RULETABLE"."FUNC_ID"="RULEFUNCTIONTABLE"."FUNC_ID")
26 - access("RGRP"."RULE_GRP_ID"="RULETABLE"."RULE_GRP_ID")
27 - access("SUB_DIM"."SUB_DIMENSION_ID"(+)="DIM"."DIMENSION_ID")
filter("SUB_DIM"."SUB_DIMENSION_ID"(+)="DIM"."DIMENSION_ID")
29 - access("DIM1"."DIMENSION_ID"(+)="SUB_DIM"."DIMENSION_ID")
Note
-----
- dynamic sampling used for this statement (level=6)
- Degree of Parallelism is 32 because of hint

oracle query taking more execution time in oracle when i m using AND condition

This below query taking more execution time when in filtering with AND Condition TD.A97 = '4408' ,and apart from them I m joining two table and two synonyms can u help me to reduce execution time for this query.
SELECT DISTINCT TC.CUS_ACNT_NBR ,
TC.CUS_ACNT_ROLE_CD ,
TD.F_DOCNUMBER,
TD.A45,
HD.SHPMNT_NBR,
HD.SHPMNT_ID
FROM TDOC_CUS_ACNT TC
INNER JOIN TDOC TD ON TD.F_DOCNUMBER = TC.F_DOCNUMBER
INNER JOIN DWH_SHIPMENT_DIM HD ON TD.A45 = HD.SHPMNT_NBR
INNER JOIN DWH_INVOICE_CHARGE_FACT ICF ON HD.shpmnt_dim_key = ICF.shipment_dim_fk
WHERE TC.CUS_ACNT_ROLE_CD in ('BILL','SHPR','THRD')
AND TD.A97 = '4408' ;
One way you can use to reduce execution time is to use parallel hints in your query.
ALTER TABLE T PARALLEL 4;
SELECT /*+ parallel(4) */ DISTINCT TC.CUS_ACNT_NBR ...
oracle docs
explain plan:below my explain plan with with AND condition.
PLAN_TABLE_OUTPUT
Plan hash value: 53520552
----------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | TQ/Ins |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1639K| 148M| | 15382 (1)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10007 | 1639K| 148M| | 15382 (1)| 00:00:01 | Q1,07 | P->S | QC (RAND) |
| 3 | HASH UNIQUE | | 1639K| 148M| 164M| 15382 (1)| 00:00:01 | Q1,07 | PCWP | |
| 4 | PX RECEIVE | | 1639K| 148M| | 15382 (1)| 00:00:01 | Q1,07 | PCWP | |
| 5 | PX SEND HASH | :TQ10006 | 1639K| 148M| | 15382 (1)| 00:00:01 | Q1,06 | P->P | HASH |
| 6 | HASH UNIQUE | | 1639K| 148M| 164M| 15382 (1)| 00:00:01 | Q1,06 | PCWP | |
|* 7 | HASH JOIN | | 1639K| 148M| | 12902 (1)| 00:00:01 | Q1,06 | PCWP | |
| 8 | PX RECEIVE | | 434K| 33M| | 8351 (1)| 00:00:01 | Q1,06 | PCWP | |
| 9 | PX SEND HASH | :TQ10005 | 434K| 33M| | 8351 (1)| 00:00:01 | Q1,05 | P->P | HASH |
|* 10 | HASH JOIN BUFFERED | | 434K| 33M| | 8351 (1)| 00:00:01 | Q1,05 | PCWP | |
| 11 | BUFFER SORT | | | | | | | Q1,05 | PCWC | |
| 12 | PX RECEIVE | | 325K| 7636K| | 2335 (1)| 00:00:01 | Q1,05 | PCWP | |
| 13 | PX SEND HASH | :TQ10001 | 325K| 7636K| | 2335 (1)| 00:00:01 | | S->P | HASH |
|* 14 | TABLE ACCESS FULL | TDOC_CUS_ACNT | 325K| 7636K| | 2335 (1)| 00:00:01 | | | |
| 15 | PX RECEIVE | | 272K| 15M| | 6015 (1)| 00:00:01 | Q1,05 | PCWP | |
| 16 | PX SEND HASH | :TQ10004 | 272K| 15M| | 6015 (1)| 00:00:01 | Q1,04 | P->P | HASH |
|* 17 | HASH JOIN | | 272K| 15M| | 6015 (1)| 00:00:01 | Q1,04 | PCWP | |
| 18 | PX RECEIVE | | 268K| 5508K| | 660 (1)| 00:00:01 | Q1,04 | PCWP | |
| 19 | PX SEND HASH | :TQ10003 | 268K| 5508K| | 660 (1)| 00:00:01 | Q1,03 | P->P | HASH |
| 20 | PX BLOCK ITERATOR | | 268K| 5508K| | 660 (1)| 00:00:01 | Q1,03 | PCWC | |
|* 21 | TABLE ACCESS FULL| TDOC | 268K| 5508K| | 660 (1)| 00:00:01 | Q1,03 | PCWP | |
| 22 | BUFFER SORT | | | | | | | Q1,04 | PCWC | |
| 23 | PX RECEIVE | | 1769K| 62M| | 5354 (1)| 00:00:01 | Q1,04 | PCWP | |
| 24 | PX SEND HASH | :TQ10000 | 1769K| 62M| | 5354 (1)| 00:00:01 | | S->P | HASH |
| 25 | REMOTE | SHIPMENT_DIM | 1769K| 62M| | 5354 (1)| 00:00:01 | TDIM | R->S | |
| 26 | BUFFER SORT | | | | | | | Q1,06 | PCWC | |
| 27 | PX RECEIVE | | 6677K| 82M| | 4550 (1)| 00:00:01 | Q1,06 | PCWP | |
| 28 | PX SEND HASH | :TQ10002 | 6677K| 82M| | 4550 (1)| 00:00:01 | | S->P | HASH |
| 29 | REMOTE | INVOICE_CHARGE_FACT | 6677K| 82M| | 4550 (1)| 00:00:01 | TDIM | R->S | |
----------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
7 - access("HD"."SHPMNT_DIM_KEY"="ICF"."SHIPMENT_DIM_FK")
10 - access("TD"."F_DOCNUMBER"="TC"."F_DOCNUMBER")
14 - filter("TC"."CUS_ACNT_ROLE_CD"='BILL' OR "TC"."CUS_ACNT_ROLE_CD"='SHPR' OR "TC"."CUS_ACNT_ROLE_CD"='THRD')
17 - access("TD"."A45"="HD"."SHPMNT_NBR")
21 - filter("TD"."A45" IS NOT NULL AND "TD"."A97"='4408')
Remote SQL Information (identified by operation id):
----------------------------------------------------
25 - SELECT "SHPMNT_DIM_KEY","SHPMNT_NBR","SHPMNT_ID" FROM "DIM"."SHIPMENT_DIM" "HD" (accessing 'TDIM.WORLD' )
29 - SELECT "SHIPMENT_DIM_FK" FROM "DIM"."INVOICE_CHARGE_FACT" "ICF" (accessing 'TDIM.WORLD' )
Note
-----
- dynamic statistics used: dynamic sampling (level=5)
- Degree of Parallelism is 16 because of table property

Oracle - Do filter predicate order change the execution plan?

We are troubleshooting a performance problem - The application uses a VIEW and filter predicates applied as below. In the first case, result is retrieved in seconds,but the second one runs for more than an hour.
columns referred in the view actually point to table D. Please note that this view was written for some other purpose and now used for an enhancement(dont know why - management decision).
I can see that the problem is FTS on the partition tables E and F, but not able to understand why/how the order of predicates change the execution plan? this is a cost based approach only and statistics are upto date.
This is not a well formed query - using % eliminates indexes etc - but what puzzles me is why the plan changes when the statement is exchanging filter predicates
select COL2 from VIEW where COL3 like
'%180%' and COL4 LIKE '%Solu%'
Plan hash value: 1618822878
------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 1379K(100)| | | |
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
|* 1 | FILTER | | | | | | | |
| 2 | NESTED LOOPS OUTER | | 116K| 8568K| 1077K (19)| 02:47:19 | | |
|* 3 | HASH JOIN RIGHT OUTER | | 97611 | 6481K| 266K (1)| 00:41:25 | | |
|* 4 | INDEX FAST FULL SCAN | IDX1_A | 45156 | 352K| 25 (8)| 00:00:01 | | |
| 5 | NESTED LOOPS | | 97611 | 5719K| 266K (1)| 00:41:25 | | |
| 6 | NESTED LOOPS | | 98629 | 5719K| 266K (1)| 00:41:25 | | |
| 7 | VIEW | VW_NSO_1 | 98629 | 674K| 82 (3)| 00:00:01 | | |
| 8 | HASH UNIQUE | | 98629 | 1338K| 82 (3)| 00:00:01 | | |
| 9 | UNION-ALL | | | | | | | |
| 10 | TABLE ACCESS FULL | B | 97591 | 667K| 80 (3)| 00:00:01 | | |
| 11 | TABLE ACCESS FULL | C | 1038 | 2076 | 2 (0)| 00:00:01 | | |
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
|* 12 | INDEX UNIQUE SCAN | PK_D | 1 | | 2 (0)| 00:00:01 | | |
|* 13 | TABLE ACCESS BY GLOBAL INDEX ROWID| D | 1 | 53 | 3 (0)| 00:00:01 | ROWID | ROWID |
| 14 | VIEW | | 1 | 7 | 8 (25)| 00:00:01 | | |
| 15 | UNION ALL PUSHED PREDICATE | | | | | | | |
| 16 | SORT UNIQUE | | 1 | 9 | 4 (25)| 00:00:01 | | |
|* 17 | INDEX RANGE SCAN | IDX1_E | 1 | 9 | 3 (0)| 00:00:01 | | |
| 18 | SORT UNIQUE | | 1 | 9 | 5 (20)| 00:00:01 | | |
|* 19 | INDEX RANGE SCAN | F | 2 | 18 | 4 (0)| 00:00:01 | | |
|* 20 | TABLE ACCESS BY INDEX ROWID | G | 1 | 36 | 3 (0)| 00:00:01 | | |
|* 21 | INDEX UNIQUE SCAN | UK_G | 1 | | 2 (0)| 00:00:01 | | |
------------------------------------------------------------------------------------------------------------------------------------
select COL2 from VIEW where COL4 LIKE '%Solu%' AND COL3 like
'%180%' ;
Plan hash value: 2380952204
-----------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Pid | Ord | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | | 24 | SELECT STATEMENT | | | | | 2598K(100)| | | |
|* 1 | 0 | 23 | FILTER | | | | | | | | |
|* 2 | 1 | 20 | HASH JOIN OUTER | | 116K| 8568K| 7632K| 2295K (2)| 05:56:38 | | |
|* 3 | 2 | 11 | HASH JOIN OUTER | | 97611 | 6481K| 6864K| 266K (1)| 00:41:27 | | |
| 4 | 3 | 9 | NESTED LOOPS | | 97611 | 5719K| | 266K (1)| 00:41:25 | | |
| 5 | 4 | 7 | NESTED LOOPS | | 98629 | 5719K| | 266K (1)| 00:41:25 | | |
| 6 | 5 | 5 | VIEW | VW_NSO_1 | 98629 | 674K| | 82 (3)| 00:00:01 | | |
| 7 | 6 | 4 | HASH UNIQUE | | 98629 | 1338K| | 82 (3)| 00:00:01 | | |
| 8 | 7 | 3 | UNION-ALL | | | | | | | | |
| 9 | 8 | 1 | TABLE ACCESS FULL | B | 97591 | 667K| | 80 (3)| 00:00:01 | | |
| 10 | 8 | 2 | TABLE ACCESS FULL | C | 1038 | 2076 | | 2 (0)| 00:00:01 | | |
|* 11 | 5 | 6 | INDEX UNIQUE SCAN | PK_D | 1 | | | 2 (0)| 00:00:01 | | |
|* 12 | 4 | 8 | TABLE ACCESS BY GLOBAL INDEX ROWID| D | 1 | 53 | | 3 (0)| 00:00:01 | ROWID | ROWID |
|* 13 | 3 | 10 | TABLE ACCESS FULL | A | 45156 | 352K| | 75 (3)| 00:00:01 | | |
| 14 | 2 | 19 | VIEW | | 127M| 851M| | 1988K (3)| 05:08:49 | | |
| 15 | 14 | 18 | UNION-ALL | | | | | | | | |
| 16 | 15 | 14 | HASH UNIQUE | | 21M| 184M| 412M| 235K (4)| 00:36:33 | | |
| 17 | 16 | 13 | PARTITION RANGE ALL | | 21M| 184M| | 164K (4)| 00:25:30 | 1 | 32 |
| 18 | 17 | 12 | TABLE ACCESS FULL | E | 21M| 184M| | 164K (4)| 00:25:30 | 1 | 32 |
| 19 | 15 | 17 | HASH UNIQUE | | 106M| 910M| 4569M| 1752K (2)| 04:32:17 | | |
| 20 | 19 | 16 | PARTITION RANGE ALL | | 238M| 2048M| | 1286K (1)| 03:19:54 | 1 | 32 |
| 21 | 20 | 15 | TABLE ACCESS FULL | F | 238M| 2048M| | 1286K (1)| 03:19:54 | 1 | 32 |
|* 22 | 1 | 22 | TABLE ACCESS BY INDEX ROWID | G | 1 | 36 | | 3 (0)| 00:00:01 | | |
|* 23 | 22 | 21 | INDEX UNIQUE SCAN | UK_G | 1 | | | 2 (0)| 00:00:01 | | |
-----------------------------------------------------------------------------------------------------------------------------------------------------

Optimize TO_TIMESTAMP() query within Oracle

every time I execute this query it takes like 2 minutes to execute:
select * from CPOB_Monitoring_Dashboard
where VOYAGE_STRT_DT >= TO_TIMESTAMP('2014-07-03 00:00:00.000','YYYY-MM-DD HH24:MI:SS.FF')
and VOYAGE_STRT_DT <= TO_TIMESTAMP('2018-07-03 00:00:00.000','YYYY-MM-DD HH24:MI:SS.FF')
However if I change it to use TO_DATE instead of TO_TIMESTAMP is really fast.
Linq is generating the query using TOTIMESTAMP and I've not found yet a way to change that to use TO_DATE, is there any way that I can optimize the TOTIMESTAMP query??
Here is the Execution Plan for the query using TOTIMESTAMP:
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 246273147
---------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 21842 | 4820K| | 1336 (1)| 00:00:17 |
| 1 | VIEW | CPOB_Monitoring_Dashboard| 21842 | 4820K| | 1336 (1)| 00:00:17 |
| 2 | HASH UNIQUE | | 21842 | 3988K| 4384K| 1336 (1)| 00:00:17 |
| 3 | NESTED LOOPS | | 21842 | 3988K| | 442 (1)| 00:00:06 |
| 4 | NESTED LOOPS | | 47 | 7661 | | 160 (1)| 00:00:02 |
|* 5 | TABLE ACCESS FULL | VOYAGE_INFO | 46 | 1012 | | 68 (0)| 00:00:01 |
| 6 | TABLE ACCESS BY INDEX ROWID| PROCESS_CTRL | 1 | 141 | | 2 (0)| 00:00:01 |
|* 7 | INDEX RANGE SCAN | VOYAGE_ID_IDX | 1 | | | 1 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | PLY_IDX2 | 467 | 11208 | | 6 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - filter(INTERNAL_FUNCTION("CPVI"."VOYAGE_STRT_DT")>=TIMESTAMP' 2014-07-03 00:00:00.000000000' AND
INTERNAL_FUNCTION("CPVI"."VOYAGE_STRT_DT")<=TIMESTAMP' 2018-07-03 00:00:00.000000000')
7 - access("CPC"."VOYAGE_ID"="CPVI"."VOYAGE_ID")
8 - access("CPC"."BRAND_NAME"="CPOB"."BRAND_ID" AND "CPC"."SHIP_NAME"=""SHIP_NAME")
filter("CPC"."SHIP_NAME"="CPOB"."SHIP_NAME")
24 rows selected.

Complicated Oracle Grouping Composite CUBE Query

I need to use the CUBE grouping function in order to get every possible combination so that this report can be used on APEX with parameters controlling how the report views. My full query is too complicated to show and will probably just confuse the situation. here I have the cutdown version
Select /*+ NO_PARALLEL */ ETP_ETPC_UID,
Decode (Grouping(ETP_ET_UID), 1, '-Grouped-', ETP_ET_UID),
/* Decode (Grouping(ETP_ET_UID), 1, '-Grouped-', ET_ABBR), */
Decode (Grouping(ETP_REFERENCE_1), 1, '-Grouped-', ETP_REFERENCE_1),
Decode (Grouping(ETP_REFERENCE_2), 1, '-Grouped-', ETP_REFERENCE_2),
Sum(ETP_COUNT)
From ETP_PROFILE,
ET_EVENT_TYPE
Where ETP_ET_UID = ET_UID
Group By
ETP_ETPC_UID,
Cube( /*(*/ETP_ET_UID/*, ET_ABBR)*/ , ETP_REFERENCE_1, ETP_REFERENCE_2)
The issue I am currently having is to do with the sections I have commented out. According to this Oracle Base article the composite column is meant to be treated as 1, so great, I can have the ET_ABBR in my query and just set ET_UID and ET_ABBR as a composite (un-comment my code and you will see).
When I do this, it seems to ridiculously increase the cost of the query (according to explain plan) and indeed it takes forever to run. If I remove my ET_ABBR column (how the code is right now with comments in place) it loads very quick and Explain plan cost is great.
Am I doing something wrong here, should I be using Grouping Sets or something like that? This is the first time I am messing with these special grouping commands, and they seem to be good, but very confusing.
EDIT:
Explain plan for Commented Query:
Plan hash value: 3169115854
------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 142K| 9M| 408 (3)| 00:00:05 | | |
| 1 | SORT GROUP BY | | 142K| 9M| 408 (3)| 00:00:05 | | |
| 2 | GENERATE CUBE | | 142K| 9M| 408 (3)| 00:00:05 | | |
| 3 | SORT GROUP BY | | 142K| 9M| 408 (3)| 00:00:05 | | |
| 4 | PARTITION RANGE ALL| | 142K| 9M| 401 (1)| 00:00:05 | 1 |1048575|
| 5 | PARTITION LIST ALL| | 142K| 9M| 401 (1)| 00:00:05 | 1 | 10 |
| 6 | TABLE ACCESS FULL| ETP_PROFILE | 142K| 9M| 401 (1)| 00:00:05 | 1 |1048575|
------------------------------------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)
Explain Plan for un-commented code:
Plan hash value: 2063641247
--------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 54 | 6426 | 427 (4)| 00:00:06 | | |
| 1 | TEMP TABLE TRANSFORMATION | | | | | | | |
| 2 | MULTI-TABLE INSERT | | | | | | | |
| 3 | SORT GROUP BY ROLLUP | | 54 | 4536 | 412 (3)| 00:00:05 | | |
|* 4 | HASH JOIN | | 142K| 11M| 406 (1)| 00:00:05 | | |
| 5 | TABLE ACCESS FULL | ET_EVENT_TYPE | 55 | 605 | 4 (0)| 00:00:01 | | |
| 6 | PARTITION RANGE ALL | | 142K| 9M| 401 (1)| 00:00:05 | 1 |1048575|
| 7 | PARTITION LIST ALL | | 142K| 9M| 401 (1)| 00:00:05 | 1 | 10 |
| 8 | TABLE ACCESS FULL | ETP_PROFILE | 142K| 9M| 401 (1)| 00:00:05 | 1 |1048575|
| 9 | DIRECT LOAD INTO | SYS_TEMP_0FD9D6E6F_E9BC1839 | | | | | | |
| 10 | DIRECT LOAD INTO | SYS_TEMP_0FD9D6E70_E9BC1839 | | | | | | |
| 11 | LOAD AS SELECT | SYS_TEMP_0FD9D6E70_E9BC1839 | | | | | | |
| 12 | SORT GROUP BY ROLLUP | | 54 | 3402 | 3 (34)| 00:00:01 | | |
| 13 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6E6F_E9BC1839 | 54 | 3402 | 2 (0)| 00:00:01 | | |
| 14 | MULTI-TABLE INSERT | | | | | | | |
| 15 | SORT GROUP BY ROLLUP | | 54 | 3240 | 3 (34)| 00:00:01 | | |
| 16 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6E6F_E9BC1839 | 54 | 3240 | 2 (0)| 00:00:01 | | |
| 17 | DIRECT LOAD INTO | SYS_TEMP_0FD9D6E71_E9BC1839 | | | | | | |
| 18 | DIRECT LOAD INTO | SYS_TEMP_0FD9D6E70_E9BC1839 | | | | | | |
| 19 | LOAD AS SELECT | SYS_TEMP_0FD9D6E70_E9BC1839 | | | | | | |
| 20 | SORT GROUP BY ROLLUP | | 54 | 2322 | 3 (34)| 00:00:01 | | |
| 21 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6E71_E9BC1839 | 54 | 2322 | 2 (0)| 00:00:01 | | |
| 22 | VIEW | | 162 | 19278 | 6 (0)| 00:00:01 | | |
| 23 | VIEW | | 162 | 15066 | 6 (0)| 00:00:01 | | |
| 24 | UNION-ALL | | | | | | | |
| 25 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6E6F_E9BC1839 | 54 | 4536 | 2 (0)| 00:00:01 | | |
| 26 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6E70_E9BC1839 | 54 | 4536 | 2 (0)| 00:00:01 | | |
| 27 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6E71_E9BC1839 | 54 | 3240 | 2 (0)| 00:00:01 | | |
--------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("SYS_TBL_$2$"."ETP_ET_UID"="SYS_TBL_$1$"."ET_UID")
Note
-----
- dynamic sampling used for this statement (level=2)

Resources