Hi Tom,
I recently started going into the performance tuning stuff, and that's when i got stuck at one of the explain plan.
Below is the Explain plan:
---------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Inst |IN-OUT|
---------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 11P| 15E| | 35G (89)|999:59:59 | | |
|* 1 | TABLE ACCESS STORAGE FULL FIRST ROWS | X_SAP_N | 1 | 56 | | 92 (0)| 00:00:02 | | |
|* 2 | TABLE ACCESS STORAGE FULL FIRST ROWS | X_SAP_N | 1 | 56 | | 92 (0)| 00:00:02 | | |
| 3 | MERGE JOIN OUTER | | 11P| 15E| | 35G (89)|999:59:59 | | |
| 4 | SORT JOIN | | 1160G| 8442T| 16P| 4115M (2)|999:59:59 | | |
|* 5 | HASH JOIN RIGHT OUTER | | 1160G| 8442T| | 112M (5)|376:30:16 | | |
|* 6 | TABLE ACCESS STORAGE FULL | X_SAP_T0 | 259 | 3885 | | 8 (0)| 00:00:01 | | |
|* 7 | HASH JOIN RIGHT OUTER | | 767G| 5573T| 54M| 109M (3)|365:28:41 | | |
| 8 | MAT_VIEW ACCESS STORAGE FULL | MVW_D_VEN | 267K| 51M| | 1376 (1)| 00:00:17 | | |
|* 9 | HASH JOIN RIGHT OUTER | | 286M| 2079G| | 1749K (1)| 05:49:56 | | |
| 10 | VIEW | VW_D_MAT | 1 | 64 | | 2 (0)| 00:00:01 | | |
| 11 | UNION-ALL | | | | | | | | |
| 12 | REMOTE | | | | | | | LNK_B~ | R->S |
| 13 | FAST DUAL | | 1 | | | 2 (0)| 00:00:01 | | |
|* 14 | HASH JOIN RIGHT OUTER | | 286M| 2062G| 23M| 1748K (1)| 05:49:46 | | |
| 15 | MAT_VIEW ACCESS STORAGE FULL | MVW_D_GEO | 79350 | 22M| | 653 (1)| 00:00:08 | | |
|* 16 | TABLE ACCESS STORAGE FULL | F_SPEND_ANALYTIC | 4662K| 32G| | 107K (1)| 00:21:36 | | |
|* 17 | SORT JOIN | | 2283K| 202M| 495M| 337K (1)| 01:07:28 | | |
| 18 | VIEW | VW_MATERIAL | 2283K| 202M| | 291K (1)| 00:58:22 | | |
|* 19 | HASH JOIN RIGHT OUTER | | 2283K| 442M| | 291K (1)| 00:58:22 | | |
| 20 | VIEW | VW_PROD | 25712 | 577K| | 171 (1)| 00:00:03 | | |
|* 21 | HASH JOIN | | 25712 | 1079K| | 171 (1)| 00:00:03 | | |
| 22 | TABLE ACCESS STORAGE FULL | X_BW_CUBE_S | 27485 | 402K| | 34 (0)| 00:00:01 | | |
|* 23 | TABLE ACCESS STORAGE FULL | X_BW_CUBE_T | 25712 | 703K| | 137 (1)| 00:00:02 | | |
|* 24 | HASH JOIN RIGHT OUTER | | 2283K| 392M| | 291K (1)| 00:58:20 | | |
| 25 | VIEW | VW_PROD | 25712 | 577K| | 171 (1)| 00:00:03 | | |
|* 26 | HASH JOIN | | 25712 | 1079K| | 171 (1)| 00:00:03 | | |
| 27 | TABLE ACCESS STORAGE FULL | X_BW_CUBE_S | 27485 | 402K| | 34 (0)| 00:00:01 | | |
|* 28 | TABLE ACCESS STORAGE FULL | X_BW_CUBE_T | 25712 | 703K| | 137 (1)| 00:00:02 | | |
|* 29 | HASH JOIN RIGHT OUTER | | 2283K| 341M| | 291K (1)| 00:58:18 | | |
| 30 | VIEW | VW_PROD | 25712 | 577K| | 171 (1)| 00:00:03 | | |
|* 31 | HASH JOIN | | 25712 | 1079K| | 171 (1)| 00:00:03 | | |
| 32 | TABLE ACCESS STORAGE FULL | X_SPROD | 27485 | 402K| | 34 (0)| 00:00:01 | | |
|* 33 | TABLE ACCESS STORAGE FULL | X_TPROD | 25712 | 703K| | 137 (1)| 00:00:02 | | |
|* 34 | HASH JOIN RIGHT OUTER | | 2283K| 291M| | 291K (1)| 00:58:16 | | |
| 35 | VIEW | VW_PROD | 25712 | 577K| | 171 (1)| 00:00:03 | | |
|* 36 | HASH JOIN | | 25712 | 1079K| | 171 (1)| 00:00:03 | | |
| 37 | TABLE ACCESS STORAGE FULL | X_SPROD | 27485 | 402K| | 34 (0)| 00:00:01 | | |
|* 38 | TABLE ACCESS STORAGE FULL | X_TPROD | 25712 | 703K| | 137 (1)| 00:00:02 | | |
|* 39 | HASH JOIN RIGHT OUTER | | 2283K| 241M| | 291K (1)| 00:58:14 | | |
| 40 | VIEW | VW_PROD | 25712 | 577K| | 171 (1)| 00:00:03 | | |
|* 41 | HASH JOIN | | 25712 | 1079K| | 171 (1)| 00:00:03 | | |
| 42 | TABLE ACCESS STORAGE FULL | X_SPROD | 27485 | 402K| | 34 (0)| 00:00:01 | | |
|* 43 | TABLE ACCESS STORAGE FULL | X_TPROD | 25712 | 703K| | 137 (1)| 00:00:02 | | |
| 44 | VIEW | VM_NWVW_0 | 2283K| 191M| | 290K (1)| 00:58:12 | | |
| 45 | HASH UNIQUE | | 2283K| 831M| 1372M| 290K (1)| 00:58:12 | | |
|* 46 | HASH JOIN | | 2283K| 831M| 230M| 117K (1)| 00:23:31 | | |
|* 47 | HASH JOIN | | 2283K| 204M| 119M| 50594 (1)| 00:10:08 | | |
|* 48 | TABLE ACCESS STORAGE FULL | X_TMATERIAL | 2283K| 93M| | 4277 (1)| 00:00:52 | | |
|* 49 | HASH JOIN | | 2282K| 111M| 78M| 33559 (1)| 00:06:43 | | |
| 50 | TABLE ACCESS STORAGE FULL| X_SMATERIAL | 2283K| 52M| | 2473 (1)| 00:00:30 | | |
|* 51 | TABLE ACCESS STORAGE FULL| X_PMATERIAL | 2282K| 58M| | 22968 (1)| 00:04:36 | | |
|* 52 | TABLE ACCESS STORAGE FULL | X_MMATERIAL | 2282K| 626M| | 23150 (1)| 00:04:38 | | |
Here i am unable to understand how the step 14 is showing 286M rows. Is there any calculation happening in the background?
A lot depends on what the optimizer thinks is the selectivity of the columns in the join. Here's a simple example:
SQL> create table t as select * from dba_objects;
Table created.
SQL> create table t1 as select * from t;
Table created.
OBJECT_ID is pretty much unique for these tables, so a join between them is a 1-to-1 relationship. And the execution plan reflects that.
SQL>
SQL> set autotrace traceonly explain
SQL>
SQL> select *
2 from t, t1
3 where t.object_id = t1.object_id(+);
Execution Plan
----------------------------------------------------------
Plan hash value: 2281690008
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 77974 | 19M| | 1912 (1)| 00:00:01 |
|* 1 | HASH JOIN OUTER | | 77974 | 19M| 10M| 1912 (1)| 00:00:01 |
| 2 | TABLE ACCESS FULL| T | 77974 | 9M| | 424 (1)| 00:00:01 |
| 3 | TABLE ACCESS FULL| T1 | 77974 | 9M| | 424 (1)| 00:00:01 |
-----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T"."OBJECT_ID"="T1"."OBJECT_ID"(+))
But what if I joined on OWNER.
SQL> select count(distinct owner) from t;
COUNT(DISTINCTOWNER)
--------------------
33
There's only 33 distinct owners, which means about 2500 rows per owner. So *each* row in T, when joined to T1 is going to give me back around 2500 rows. Hence that is a dramatic multiplying effect, and the optimizer reflects this:
SQL>
SQL> select *
2 from t, t1
3 where t.owner = t1.owner(+);
Execution Plan
----------------------------------------------------------
Plan hash value: 2281690008
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 184M| 45G| | 2802 (33)| 00:00:01 |
|* 1 | HASH JOIN OUTER | | 184M| 45G| 10M| 2802 (33)| 00:00:01 |
| 2 | TABLE ACCESS FULL| T | 77974 | 9M| | 424 (1)| 00:00:01 |
| 3 | TABLE ACCESS FULL| T1 | 77974 | 9M| | 424 (1)| 00:00:01 |
-----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T"."OWNER"="T1"."OWNER"(+))