Oracle - Do filter predicate order change the execution plan? - oracle

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 | | |
-----------------------------------------------------------------------------------------------------------------------------------------------------

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

Buffers used by WINDOW SORT operation

I have a query with the following execution plan:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 21741 |00:00:11.38 | 150K| 1088 | | | |
| 1 | SORT AGGREGATE | | 46072 | 1 | 46072 |00:00:02.92 | 138K| 241 | | | |
| 2 | FIRST ROW | | 46072 | 1 | 3761 |00:00:02.83 | 138K| 241 | | | |
|* 3 | INDEX RANGE SCAN (MIN/MAX) | VERP_VIG_VEHICLE_STAGES_N2 | 46072 | 1 | 3761 |00:00:02.79 | 138K| 241 | | | |
|* 4 | HASH JOIN RIGHT OUTER | | 1 | 37010 | 21741 |00:00:11.38 | 150K| 1088 | 3272K| 1218K| 3302K (0)|
| 5 | VIEW | | 1 | 7402 | 23548 |00:00:11.17 | 147K| 1088 | | | |
| 6 | WINDOW SORT | | 1 | 7402 | 23548 |00:00:10.82 | 79621 | 1088 | 4801K| 915K| 4267K (0)|
|* 7 | HASH JOIN RIGHT OUTER | | 1 | 7402 | 23548 |00:00:07.84 | 8837 | 847 | 1599K| 1599K| 996K (0)|
| 8 | TABLE ACCESS FULL | VERP_OTM_PS_CONTROL_TABLE | 1 | 5 | 5 |00:00:00.01 | 39 | 0 | | | |
|* 9 | FILTER | | 1 | | 23548 |00:00:07.80 | 8798 | 847 | | | |
|* 10 | HASH JOIN RIGHT OUTER | | 1 | 7402 | 71904 |00:00:07.76 | 8798 | 847 | 1421K| 1421K| 1756K (0)|
| 11 | VIEW | | 1 | 4534 | 4554 |00:00:00.01 | 27 | 0 | | | |
|* 12 | HASH JOIN | | 1 | 4534 | 4554 |00:00:00.01 | 27 | 0 | 1888K| 1888K| 1596K (0)|
| 13 | INDEX FULL SCAN | VERP_VPS_SUPPLY_VVP_N1 | 1 | 27 | 27 |00:00:00.01 | 1 | 0 | | | |
| 14 | INDEX FULL SCAN | VERP_VPS_SUPPLY_VVVP_N1 | 1 | 4534 | 4554 |00:00:00.01 | 26 | 0 | | | |
|* 15 | HASH JOIN | | 1 | 37010 | 71904 |00:00:07.67 | 8771 | 847 | 1245K| 1245K| 1722K (0)|
| 16 | SORT UNIQUE | | 1 | 37010 | 1586 |00:00:00.05 | 3279 | 0 | 124K| 124K| 110K (0)|
| 17 | TABLE ACCESS FULL | VERP_OTM_STAGED_VONS | 1 | 37010 | 21741 |00:00:00.02 | 3279 | 0 | | | |
| 18 | TABLE ACCESS BY INDEX ROWID BATCHED| VERP_VIG_VEHICLES | 1 | 246K| 36104 |00:00:07.53 | 5492 | 847 | | | |
|* 19 | INDEX RANGE SCAN | VERP_VIG_VEHICLES_N22 | 1 | 246K| 36104 |00:00:07.38 | 891 | 838 | | | |
| 20 | VIEW | | 1 | 37010 | 21741 |00:00:00.12 | 3279 | 0 | | | |
| 21 | WINDOW SORT | | 1 | 37010 | 21741 |00:00:00.11 | 3279 | 0 | 1612K| 624K| 1432K (0)|
| 22 | TABLE ACCESS FULL | VERP_OTM_STAGED_VONS | 1 | 37010 | 21741 |00:00:00.03 | 3279 | 0 | | | |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("S"."VIN"=:B1 AND "S"."STAGE_CODE"='YARD_RECEIPT')
4 - access("VINS"."VIN_SEQUENCE"="VONS"."VON_SEQUENCE" AND "VINS"."PORT_CODE"="VONS"."PORT_CODE" AND "VINS"."INT_COLOR_CODE"="VONS"."INT_COLOR_CODE" AND
"VINS"."EXT_COLOR_CODE"="VONS"."EXT_COLOR_CODE" AND "VINS"."SPEC_CODE"="VONS"."SPEC_CODE" AND "VINS"."OPTION_CODE"="VONS"."OPTION_CODE" AND
"VINS"."MODEL_CODE"="VONS"."MODEL_CODE")
7 - access("C"."PORT"=CASE "VVV"."VEHICLE_SOURCE" WHEN 'SIA' THEN '020' ELSE "from$_subquery$_006"."PORT_CODE" END )
9 - filter("VPT"."PORT"=CASE "VVV"."VEHICLE_SOURCE" WHEN 'SIA' THEN '020' ELSE "from$_subquery$_006"."PORT_CODE" END )
10 - access("VVVP"."VESSEL_PORT_ID"="VVV"."VESSEL_PORT_ID")
12 - access("VVP"."PORT_ID"="VVVP"."PORT_ID")
15 - access("VVV"."SOA_MODEL_CODE"="VPT"."MODEL_CODE" AND "VVV"."SOA_OPTION_CODE"="VPT"."OPTION_CODE" AND "VVV"."SOA_SPEC_CODE"="VPT"."SPEC_CODE" AND
"VVV"."SOA_EXT_COLOR_CODE"="VPT"."EXT_COLOR_CODE" AND "VVV"."SOA_INT_COLOR_CODE"="VPT"."INT_COLOR_CODE")
19 - access("VVV"."PS_STATUS"='NOT_MATCHED')
I am interested to know why the WINDOW SORT operation in step #6 is requiring so many buffer gets. I usually don't see that sort of thing for a WINDOW SORT operation. For example see the operation in step 21 of the same plan -- no additional buffer gets.
Does anyone know what these buffer gets are? I suspect that maybe the sort operation is spilling to disk, due to its size, and the extra buffer gets are to access those temp tablespace blocks. I'd like confirmation or alternate explanations, as appropriate. Thanks.
UPDATE
To hopefully clarify: I want to know why step 6 required added buffer gets beyond what was required to get through step 7. I.e., why it is not like the buffer gets in step 21, which did not increase the number from what was necessary to get through step 22.

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)

Oracle LEFT JOIN View 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.

Oracle 10g database optimization

Sorry for my English.
I have so big DB on Oracle 10g.
And I have queries, which executed so slow. For example, I have query :
115559 rows – 102 seconds
Execution plan:
Plan hash value: 3664903106
------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------------------------
| 1 | SORT ORDER BY | | 1 | 30503 | 50 |00:00:09.33 | 3989 | 33M| 2065K| 29M (0)|
|* 2 | HASH JOIN RIGHT OUTER | | 1 | 30503 | 115K|00:00:05.71 | 3989 | 862K| 862K| 1186K (0)|
| 3 | INDEX FAST FULL SCAN | IX2_SLCND | 1 | 1387 | 1387 |00:00:00.01 | 17 | | | |
|* 4 | HASH JOIN RIGHT OUTER | | 1 | 30503 | 115K|00:00:05.47 | 3972 | 785K| 785K| 1145K (0)|
| 5 | TABLE ACCESS FULL | DISC | 1 | 90 | 90 |00:00:00.01 | 7 | | | |
|* 6 | HASH JOIN RIGHT OUTER | | 1 | 30503 | 115K|00:00:05.24 | 3965 | 776K| 776K| 403K (0)|
| 7 | VIEW | index$_join$_030 | 1 | 2 | 2 |00:00:00.01 | 6 | | | |
|* 8 | HASH JOIN | | 1 | | 2 |00:00:00.01 | 6 | 760K| 760K| 464K (0)|
| 9 | INDEX FAST FULL SCAN | IX_CMP_NAME | 1 | 2 | 2 |00:00:00.01 | 3 | | | |
| 10 | INDEX FAST FULL SCAN | PK_CMP | 1 | 2 | 2 |00:00:00.01 | 3 | | | |
|* 11 | HASH JOIN RIGHT OUTER | | 1 | 30503 | 115K|00:00:05.01 | 3959 | 756K| 756K| 1066K (0)|
| 12 | TABLE ACCESS FULL | TTYPE | 1 | 26 | 27 |00:00:00.01 | 7 | | | |
|* 13 | HASH JOIN RIGHT OUTER | | 1 | 30503 | 115K|00:00:04.78 | 3952 | 767K| 767K| 416K (0)|
| 14 | TABLE ACCESS FULL | COMMTCOMP | 1 | 2 | 2 |00:00:00.01 | 7 | | | |
|* 15 | HASH JOIN RIGHT OUTER | | 1 | 30503 | 115K|00:00:04.54 | 3945 | 760K| 760K| 1037K (0)|
| 16 | TABLE ACCESS FULL | TTYPE | 1 | 26 | 27 |00:00:00.01 | 7 | | | |
|* 17 | HASH JOIN RIGHT OUTER | | 1 | 30503 | 115K|00:00:04.31 | 3938 | 842K| 842K| 1267K (0)|
| 18 | TABLE ACCESS FULL | SLRSSEASONTC | 1 | 2885 | 2974 |00:00:00.01 | 53 | | | |
|* 19 | HASH JOIN RIGHT OUTER | | 1 | 30503 | 115K|00:00:04.07 | 3885 | 909K| 909K| 1178K (0)|
| 20 | TABLE ACCESS FULL | CAR | 1 | 976 | 976 |00:00:00.01 | 16 | | | |
|* 21 | HASH JOIN RIGHT OUTER | | 1 | 30503 | 115K|00:00:03.84 | 3869 | 1036K| 1036K| 1169K (0)|
| 22 | INDEX FULL SCAN | PK_STP | 1 | 258 | 258 |00:00:00.01 | 1 | | | |
|* 23 | HASH JOIN | | 1 | 30503 | 115K|00:00:03.60 | 3868 | 778K| 778K| 1165K (0)|
| 24 | TABLE ACCESS FULL | WKST | 1 | 83 | 83 |00:00:00.01 | 7 | | | |
|* 25 | HASH JOIN | | 1 | 61027 | 115K|00:00:03.37 | 3861 | 804K| 804K| 924K (0)|
| 26 | VIEW | index$_join$_014 | 1 | 12 | 12 |00:00:00.01 | 6 | | | |
|* 27 | HASH JOIN | | 1 | | 12 |00:00:00.01 | 6 | 783K| 783K| 919K (0)|
| 28 | INDEX FAST FULL SCAN | IX_BRANCH_NAME | 1 | 12 | 12 |00:00:00.01 | 3 | | | |
| 29 | INDEX FAST FULL SCAN | PK_BRANCH | 1 | 12 | 12 |00:00:00.01 | 3 | | | |
|* 30 | HASH JOIN | | 1 | 61027 | 115K|00:00:03.13 | 3855 | 808K| 808K| 1166K (0)|
| 31 | TABLE ACCESS FULL | USERS | 1 | 96 | 96 |00:00:00.01 | 16 | | | |
| 32 | MERGE JOIN | | 1 | 115K| 115K|00:00:02.90 | 3839 | | | |
|* 33 | HASH JOIN RIGHT OUTER| | 1 | 115K| 115K|00:00:02.32 | 3838 | 848K| 848K| 1169K (0)|
| 34 | TABLE ACCESS FULL | STP | 1 | 258 | 258 |00:00:00.01 | 7 | | | |
|* 35 | HASH JOIN | | 1 | 115K| 115K|00:00:01.95 | 3831 | 848K| 848K| 1169K (0)|
| 36 | TABLE ACCESS FULL | STP | 1 | 258 | 258 |00:00:00.01 | 7 | | | |
|* 37 | HASH JOIN | | 1 | 115K| 115K|00:00:01.52 | 3824 | 848K| 848K| 1169K (0)|
| 38 | TABLE ACCESS FULL | STP | 1 | 258 | 258 |00:00:00.01 | 7 | | | |
|* 39 | HASH JOIN | | 1 | 115K| 115K|00:00:01.09 | 3817 | 10M| 1956K| 12M (0)|
|* 40 | TABLE ACCESS FULL| SL | 1 | 116K| 120K|00:00:00.01 | 2115 | | | |
|* 41 | TABLE ACCESS FULL| SLTC | 1 | 114K| 115K|00:00:00.19 | 1702 | | | |
|* 42 | SORT JOIN | | 115K| 1 | 115K|00:00:00.27 | 1 | 73728 | 73728 | |
|* 43 | INDEX UNIQUE SCAN | PK_CMP | 1 | 1 | 1 |00:00:00.01 | 1 | | | |
------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("SLCND"."ID"="SL"."ID")
4 - access("SL"."DISC_ID"="DISC"."ID")
6 - access("CARI"."ID"="SLTC"."CARI_ID")
8 - access(ROWID=ROWID)
11 - access("TTYPE"."ID"="SLTC"."TTYPE_ID")
13 - access("CTC"."ID"="SLRSSEASONTC "."ID_COMMTCOMP")
15 - access("RS"."ID"="SLRSSEASONTC "."COMMTTYPE_ID")
17 - access("SLRSSEASONTC "."ID"="SLTC"."ID")
19 - access("CAR"."ID"="SLTC"."CAR_ID")
21 - access("STP"."ID"="WKST"."DEF_STP_ID")
23 - access("SL"."POS_WKST_ID"="WKST"."ID")
25 - access("USERS"."BRANCH_ID"="BRANCH"."ID")
27 - access(ROWID=ROWID)
30 - access("SL"."USR_CAS_ID"="USERS"."ID")
33 - access("SLTC"."THSTP_ID"="THSTP"."ID")
35 - access("SLTC"."TSTP_ID"="TSTP"."ID")
37 - access("SLTC"."FSTP_ID"="FSTP"."ID")
39 - access("SLTC"."ID"="SL"."ID")
40 - filter(("SL"."WHEN_DATE">=TO_DATE('2001-10-29 00:00:00', 'yyyy-mm-dd hh24:mi:ss') AND "SL"."SCOMP_ID"=1 AND
"SL"."WHEN_DATE"<=TO_DATE('2013-10-29 23:59:59', 'yyyy-mm-dd hh24:mi:ss')))
41 - filter("SLTC"."MANUAL"='N')
42 - access("SL"."SCOMP_ID"="CMP"."ID")
filter("SL"."SCOMP_ID"="CMP"."ID")
43 - access("CMP"."ID"=1)
I need ideas to make db faster.
Thanks You!
p.s.
I’m new in databases
So yeah, a you have a pretty horrible execution plan there.
To optimise the query, we would need the query as well, but I'll try to give you a few hints using just your exection plan output.
See all the TABLE ACCESS FULL? This is what usually takes time! Try using indexes on your tables, it seems that there are too few indexes used here (probably because no other indexes exist). Based on the execution plan, here are some simple indexes that might work, you may try them out:
CREATE INDEX ix_sltc_id ON sltc(ID);
CREATE INDEX ix_sl_id ON sl(ID);
CREATE INDEX ix_sltc_manual ON sltc(manual);
CREATE INDEX ix_sl_scomp_id ON sl(SCOMP_ID);
CREATE INDEX ix_sl_pos_wkst_id ON sl(POS_WKST_ID);
CREATE INDEX ix_sltc_thstp_id ON sltc(THSTP_ID)
CREATE INDEX ix_sltc_thstp_id ON sltc(THSTP_ID);
CREATE INDEX ix_sltc_tstp_id ON sltc(TSTP_ID);
CREATE INDEX ix_sltc_fstp_id ON sltc(FSTP_ID);
Without the query itself, we are quite limited here and probably missing most of the picture. Using the query, we could then try to create composite indexes, that are much more efficient.
More importantly, it seems that you do not use PRIMARY KEYs on your tables, because there are a lot of TABLE ACCESS FULL operations on tables with the predicate "ID". Make sure all your "ID" columns are indexed as well (or defined as PRIMARY KEY if that is indeed the primary key).
Also, we see that the optimizer does not have correct statistics, try to manually refresh the statistics for your schema:
EXEC DBMS_STATS.delete_schema_stats('SCOTT');
And as a sidenote: Whoever designed this schema, educate this person on database design!
Another sidenote for the more advanced readers: While TABLE ACCESS FULL is not always bad (there are quite a few cases where a full table scan is faster than access via indexes), it often indicates missing indexes. So setting the indexes and refreshing the statistics should provide a performance gain here.

Resources