select count(*)
from
(
select /*+ gather_plan_statistics */
t1.c1, t1.c2
from
t1
where
t1.c1 in (select rownum from t2)
)
;
@stat
-------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | Cost (%CPU)| A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------------------
| 1 | SORT AGGREGATE | | 1 | 1 | | 1 |00:00:00.01 | 31 | | | |
|* 2 | HASH JOIN | | 1 | 1000 | 12 (17)| 1000 |00:00:00.02 | 31 | 1517K| 1517K| 1201K (0)|
| 3 | VIEW | VW_NSO_1 | 1 | 1000 | 4 (25)| 1000 |00:00:00.01 | 7 | | | |
| 4 | HASH UNIQUE | | 1 | 1000 | 4 (25)| 1000 |00:00:00.01 | 7 | 1453K| 1453K| 1226K (0)|
| 5 | COUNT | | 1 | | | 1000 |00:00:00.01 | 7 | | | |
| 6 | TABLE ACCESS FULL| T2 | 1 | 1000 | 3 (0)| 1000 |00:00:00.01 | 7 | | | |
| 7 | INDEX FAST FULL SCAN| T1_N1 | 1 | 10000 | 7 (0)| 10000 |00:00:00.03 | 24 | | | |
-------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("T1"."C1"="$nso_col_1")
ROWNUM이 포함된 Subquery는 Main Query안으로 바로 Unnesting 하는 것이 불가능하다.
이경우 Oracle은 Subquery를 View로 변환하고 가능한 Filter Operation을 회피하게끔 실행계획을 수립한다.
-- Filter Operation
select count(*)
from
(
select /*+ gather_plan_statistics */
t1.c1, t1.c2
from
t1
where
t1.c1 in (select /*+ no_unnest */ rownum from t2)
)
;
@stat
-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | Cost (%CPU)| A-Rows | A-Time | Buffers |
-----------------------------------------------------------------------------------------------------
| 1 | SORT AGGREGATE | | 1 | 1 | | 1 |00:00:07.92 | 68883 |
|* 2 | FILTER | | 1 | | | 1000 |00:00:00.62 | 68883 |
| 3 | TABLE ACCESS FULL | T1 | 1 | 10000 | 11 (0)| 10000 |00:00:00.04 | 38 |
|* 4 | FILTER | | 10000 | | | 1000 |00:00:07.85 | 68845 |
| 5 | COUNT | | 10000 | | | 9500K|00:01:35.29 | 68845 |
| 6 | TABLE ACCESS FULL| T2 | 10000 | 1000 | 3 (0)| 9500K|00:00:38.50 | 68845 |
-----------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter( IS NOT NULL)
4 - filter(ROWNUM=:B1)
select /*+ gather_plan_statistics */
t1.c1, t1.c2
from
t1
where
t1.c1 in (select c1 from t2
union all
select c1 from t3)
;
@stat
---------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | Cost (%CPU)| A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem |
---------------------------------------------------------------------------------------------------------------------------------------------
|* 1 | HASH JOIN | | 1 | 1101K| 23 (35)| 1000 |00:00:00.04 | 119 | 6 | 1517K| 1517K| 1469K (0)|
| 2 | VIEW | VW_NSO_1 | 1 | 1100 | 4 (0)| 1000 |00:00:00.04 | 14 | 6 | | | |
| 3 | HASH UNIQUE | | 1 | | | 1000 |00:00:00.03 | 14 | 6 | 1453K| 1453K| 1229K (0)|
| 4 | UNION-ALL | | 1 | | | 1100 |00:00:00.02 | 14 | 6 | | | |
| 5 | TABLE ACCESS FULL| T2 | 1 | 1000 | 3 (0)| 1000 |00:00:00.01 | 7 | 0 | | | |
| 6 | TABLE ACCESS FULL| T3 | 1 | 100 | 3 (0)| 100 |00:00:00.02 | 7 | 6 | | | |
| 7 | TABLE ACCESS FULL | T1 | 1 | 10000 | 11 (0)| 10000 |00:00:00.03 | 105 | 0 | | | |
---------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T1"."C1"="$nso_col_1")
select /*+ gather_plan_statistics */
t1.c1, t1.c2
from
t1
where
t1.c1 in (select c1 from t2
union all
select c1 from t3)
and t1.c1 between 1 and 100
;
@stat
----------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | Cost (%CPU)| A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------------------------------------
|* 1 | HASH JOIN | | 1 | 1 | 6 (17)| 100 |00:00:00.04 | 20 | 1 | 1517K| 1517K| 1197K (0)|
| 2 | VIEW | VW_NSO_1 | 1 | 3 | 2 (0)| 100 |00:00:00.04 | 3 | 1 | | | |
| 3 | HASH UNIQUE | | 1 | | | 100 |00:00:00.04 | 3 | 1 | 1518K| 1518K| 1229K (0)|
| 4 | UNION-ALL PARTITION | | 1 | | | 200 |00:00:00.01 | 3 | 1 | | | |
|* 5 | INDEX RANGE SCAN | T2_N1 | 1 | 100 | 2 (0)| 100 |00:00:00.01 | 2 | 0 | | | |
|* 6 | INDEX RANGE SCAN | T3_N1 | 1 | 100 | 1 (0)| 100 |00:00:00.03 | 1 | 1 | | | |
| 7 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 100 | 3 (0)| 100 |00:00:00.01 | 17 | 0 | | | |
|* 8 | INDEX RANGE SCAN | T1_N1 | 1 | 100 | 2 (0)| 100 |00:00:00.01 | 9 | 0 | | | |
----------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T1"."C1"="$nso_col_1")
5 - access("C1">=1 AND "C1"<=100)
6 - access("C1">=1 AND "C1"<=100)
8 - access("T1"."C1">=1 AND "T1"."C1"<=100)
select /*+ gather_plan_statistics
opt_param('_remove_aggr_subquery','false') */
t1.c1, t2.c2
from
t1, t2
where
t1.c1 = t2.c1 and
t2.c2 = (select max(c2) from t2 s where s.c1 = t1.c1)
;
@stat
------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | Cost (%CPU)| A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------------
|* 1 | HASH JOIN | | 1 | 1000 | 15 (14)| 1000 |00:00:00.04 | 105 | 1000K| 1000K| 1226K (0)|
| 2 | TABLE ACCESS FULL | T2 | 1 | 1000 | 3 (0)| 1000 |00:00:00.01 | 7 | | | |
|* 3 | HASH JOIN | | 1 | 1000 | 12 (17)| 1000 |00:00:00.03 | 98 | 1095K| 1095K| 1210K (0)|
| 4 | VIEW | VW_SQ_1 | 1 | 1000 | 4 (25)| 1000 |00:00:00.01 | 7 | | | |
| 5 | HASH GROUP BY | | 1 | 1000 | 4 (25)| 1000 |00:00:00.01 | 7 | 1049K| 1049K| 1189K (0)|
| 6 | TABLE ACCESS FULL | T2 | 1 | 1000 | 3 (0)| 1000 |00:00:00.01 | 7 | | | |
| 7 | INDEX FAST FULL SCAN| T1_N1 | 1 | 10000 | 7 (0)| 10000 |00:00:00.04 | 91 | | | |
------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T1"."C1"="T2"."C1" AND "T2"."C2"="VW_COL_1")
3 - access("C1"="T1"."C1")
select /*+ gather_plan_statistics
opt_param('_remove_aggr_subquery','true') */
t1.c1, t2.c2
from
t1, t2
where
t1.c1 = t2.c1 and
t2.c2 = (select max(c2) from t2 s where s.c1 = t1.c1)
;
@stat
---------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
---------------------------------------------------------------------------------------------------------------------------------------------------------
|* 1 | VIEW | VW_WIF_1 | 1 | 1000 | 37000 | 12 (17)| 00:00:01 | 1000 |00:00:00.02 | 31 | | | |
| 2 | WINDOW SORT | | 1 | 1000 | 21000 | 12 (17)| 00:00:01 | 1000 |00:00:00.01 | 31 | 59392 | 59392 |53248 (0)|
|* 3 | HASH JOIN | | 1 | 1000 | 21000 | 11 (10)| 00:00:01 | 1000 |00:00:00.02 | 31 | 955K| 955K| 1177K (0)|
| 4 | TABLE ACCESS FULL | T2 | 1 | 1000 | 17000 | 3 (0)| 00:00:01 | 1000 |00:00:00.01 | 7 | | | |
| 5 | INDEX FAST FULL SCAN| T1_N1 | 1 | 10000 | 40000 | 7 (0)| 00:00:01 | 10000 |00:00:00.04 | 24 | | | |
---------------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("VW_COL_3" IS NOT NULL)
3 - access("T1"."C1"="T2"."C1")
select * from
table(dbms_xplan.display_cursor(null, null, 'all allstats cost last'));
Column Projection Information (identified by operation id):
-----------------------------------------------------------
1 - "C1"[NUMBER,22], "C2"[CHARACTER,10], "VW_COL_3"[ROWID,10]
2 - (#keys=1) "T2"."C1"[NUMBER,22], "T2"."C2"[CHARACTER,10], "T1"."C1"[NUMBER,22], ROWID[ROWID,10], MAX("C2") OVER ( PARTITION BY
"S"."C1")[10]
3 - (#keys=1) "T2"."C1"[NUMBER,22], "T1"."C1"[NUMBER,22], ROWID[ROWID,10], "T2"."C2"[CHARACTER,10]
4 - ROWID[ROWID,10], "T2"."C1"[NUMBER,22], "T2"."C2"[CHARACTER,10]
5 - "T1"."C1"[NUMBER,22]
- 강좌 URL : http://www.gurubee.net/lecture/3874
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.