SQL> SELECT * FROM V$VERSION WHERE ROWNUM <= 1;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
CREATE TABLE 고객
AS
SELECT LEVEL 고객번호
, MOD(LEVEL, 3) + 1 납입방법코드
, DEcode(MOD(LEVEL, 10)
, 1, '서울', 2, '대전', 3, '대구', 4, '부산', 5, '찍고'
, 6, '아하', 7, '경기', 8, '충청', 9, '전라', 0, '경상'
) 거주지역
FROM dual
CONNECT BY LEVEL <= 100000
;
ALTER TABLE 고객 ADD CONSTRAINT pk_고객 PRIMARY KEY(고객번호);
CREATE INDEX idx_1 ON 고객(거주지역);
CREATE INDEX idx_2 ON 고객(납입방법코드);
EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, '고객', CASCADE => TRUE);
CREATE TABLE 납입방법
AS
SELECT 1 납입방법코드, '신용카드' 납입방법 FROM dual
UNION ALL SELECT 2, '자동이체' FROM dual
UNION ALL SELECT 3, '지로' FROM dual
;
ALTER TABLE 납입방법
ADD CONSTRAINT pk_납입방법 PRIMARY KEY(납입방법코드)
EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, '납입방법', CASCADE => TRUE);
;
SQL> SELECT COUNT(*)--a.납입방법명, b.*
2 FROM 납입방법 a, 고객 b
3 WHERE b.납입방법코드 = a.납입방법코드
4 ;
COUNT(*)--A.납입방법명,B.*
--------------------------
100000
SQL> @XPLAN
-----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.09 | 205 | | | |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.09 | 205 | | | |
|* 2 | HASH JOIN | | 1 | 100K| 100K|00:00:00.08 | 205 | 1517K| 1517K| 821K (0)|
| 3 | INDEX FULL SCAN | PK_납입 | 1 | 3 | 3 |00:00:00.01 | 1 | | | |
| 4 | INDEX FAST FULL SCAN| IDX_2 | 1 | 100K| 100K|00:00:00.02 | 204 | | | |
-----------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("B"."납입방법코드"="A"."납입방법코드")
SQL> SELECT /*+ LEADING(b) USE_NL(a) INDEX( A ) */
2 a.납입방법, b.*
3 FROM 납입방법 a, 고객 b
4 WHERE b.납입방법코드 = a.납입방법코드
5 ;
...
SQL> @XPLAN
-----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
-----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 100K|00:00:00.57 | 113K| 251 |
| 1 | NESTED LOOPS | | 1 | | 100K|00:00:00.57 | 113K| 251 |
| 2 | NESTED LOOPS | | 1 | 100K| 100K|00:00:00.38 | 13536 | 250 |
| 3 | TABLE ACCESS FULL | 고객 | 1 | 100K| 100K|00:00:00.20 | 6866 | 249 |
|* 4 | INDEX UNIQUE SCAN | PK_납입 | 100K| 1 | 100K|00:00:00.11 | 6670 | 1 |
| 5 | TABLE ACCESS BY INDEX ROWID| 납입방법| 100K| 1 | 100K|00:00:00.13 | 100K| 1 |
-----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("B"."납입방법코드"="A"."납입방법코드")
SQL> SELECT /*+ LEADING(A) USE_NL(B) INDEX( B ) */
2 a.납입방법, b.*
3 FROM 납입방법 a, 고객 b
4 WHERE b.납입방법코드 = a.납입방법코드
5 ;
...
SQL> @XPLAN
Plan hash value: 1253683656
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
---------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 100K|00:00:00.35 | 14219 | 200 |
| 1 | NESTED LOOPS | | 1 | | 100K|00:00:00.35 | 14219 | 200 |
| 2 | NESTED LOOPS | | 1 | 100K| 100K|00:00:00.20 | 6860 | 197 |
| 3 | TABLE ACCESS FULL | 납입방| 1 | 3 | 3 |00:00:00.01 | 5 | 0 |
|* 4 | INDEX RANGE SCAN | IDX_2 | 3 | 33333 | 100K|00:00:00.17 | 6855 | 197 |
| 5 | TABLE ACCESS BY INDEX ROWID| 고객 | 100K| 33333 | 100K|00:00:00.08 | 7359 | 3 |
---------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("B"."납입방법코드"="A"."납입방법코드")
SQL> SELECT /*+ LEADING(b) USE_NL(a) INDEX( A ) INDEX( B ) */
2 a.납입방법, b.*
3 FROM 납입방법 a, 고객 b
4 WHERE b.납입방법코드 = a.납입방법코드
5 AND b.거주지역 = '부산'
...
SQL> @XPLAN
------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 10000 |00:00:00.70 | 12263 | 24 |
| 1 | NESTED LOOPS | | 1 | | 10000 |00:00:00.70 | 12263 | 24 |
| 2 | NESTED LOOPS | | 1 | 10000 | 10000 |00:00:00.68 | 2263 | 24 |
| 3 | TABLE ACCESS BY INDEX ROWID| 고객 | 1 | 10000 | 10000 |00:00:00.66 | 1593 | 24 |
|* 4 | INDEX RANGE SCAN | IDX_1 | 1 | 10000 | 10000 |00:00:00.66 | 689 | 24 |
|* 5 | INDEX UNIQUE SCAN | PK_납입 | 10000 | 1 | 10000 |00:00:00.01 | 670 | 0 |
| 6 | TABLE ACCESS BY INDEX ROWID | 납입방법| 10000 | 1 | 10000 |00:00:00.01 | 10000 | 0 |
------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("B"."거주지역"='부산')
5 - access("B"."납입방법코드"="A"."납입방법코드")
SQL> SELECT /*+ LEADING(A) USE_NL(B) INDEX( B idx_2 ) */
2 a.납입방법, b.*
3 FROM 납입방법 a, 고객 b
4 WHERE b.납입방법코드 = a.납입방법코드
5 AND b.거주지역 = '부산'
;
...
SQL> @XPLAN
------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 10000 |00:00:00.15 | 2276 |
| 1 | NESTED LOOPS | | 1 | | 10000 |00:00:00.15 | 2276 |
| 2 | NESTED LOOPS | | 1 | 10000 | 100K|00:00:00.05 | 871 |
| 3 | TABLE ACCESS FULL | 납입방| 1 | 3 | 3 |00:00:00.01 | 5 |
|* 4 | INDEX RANGE SCAN | IDX_2 | 3 | 33333 | 100K|00:00:00.03 | 866 |
|* 5 | TABLE ACCESS BY INDEX ROWID| 고객 | 100K| 3333 | 10000 |00:00:00.06 | 1405 |
------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("B"."납입방법코드"="A"."납입방법코드")
5 - filter("B"."거주지역"='부산')
SQL> CREATE INDEX idx_3 ON 고객(거주지역, 납입방법코드);
인덱스가 생성되었습니다.
SQL> SELECT /*+ LEADING(A) USE_NL(B) INDEX( B idx_3 ) */
2 a.납입방법, b.*
3 FROM 납입방법 a, 고객 b
4 WHERE b.납입방법코드 = a.납입방법코드
5 AND b.거주지역 = '부산'
...
SQL> @XPLAN
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
---------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 10000 |00:00:00.03 | 2063 | 27 |
| 1 | NESTED LOOPS | | 1 | | 10000 |00:00:00.03 | 2063 | 27 |
| 2 | NESTED LOOPS | | 1 | 10000 | 10000 |00:00:00.01 | 703 | 27 |
| 3 | TABLE ACCESS FULL | 납입방| 1 | 3 | 3 |00:00:00.01 | 5 | 0 |
|* 4 | INDEX RANGE SCAN | IDX_3 | 3 | 3333 | 10000 |00:00:00.01 | 698 | 27 |
| 5 | TABLE ACCESS BY INDEX ROWID| 고객 | 10000 | 3333 | 10000 |00:00:00.01 | 1360 | 0 |
---------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("B"."거주지역"='부산' AND "B"."납입방법코드"="A"."납입방법코드")
SQL> SELECT /*+ LEADING(b) USE_MERGE(a) */
2 a.납입방법, b.*
3 FROM 납입방법 a, 고객 b
4 WHERE b.납입방법코드 = a.납입방법코드
5 ;
...
SQL> @XPLAN
-----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 100K|00:00:00.26 | 255 | | | |
| 1 | MERGE JOIN | | 1 | 100K| 100K|00:00:00.26 | 255 | | | |
| 2 | SORT JOIN | | 1 | 100K| 100K|00:00:00.10 | 252 | 3738K| 834K| 3322K (0)|
| 3 | TABLE ACCESS FULL| 고객 | 1 | 100K| 100K|00:00:00.02 | 252 | | | |
|* 4 | SORT JOIN | | 100K| 3 | 100K|00:00:00.10 | 3 | 2048 | 2048 | 2048 (0)|
| 5 | TABLE ACCESS FULL| 납입 | 1 | 3 | 3 |00:00:00.01 | 3 | | | |
-----------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("B"."납입방법코드"="A"."납입방법코드")
filter("B"."납입방법코드"="A"."납입방법코드")
--INDEX
SELECT /*+ LEADING(b) INDEX( B PK_고객 ) USE_MERGE(a) */
a.납입방법, b.*
FROM 납입방법 a, 고객 b
WHERE b.납입방법코드 = a.납입방법코드;
----------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 100K|00:00:00.31 | 460 | | | |
| 1 | MERGE JOIN | | 1 | 100K| 100K|00:00:00.31 | 460 | | | |
| 2 | SORT JOIN | | 1 | 100K| 100K|00:00:00.16 | 457 | 3738K| 834K| 3322K (0)|
| 3 | TABLE ACCESS BY INDEX ROWID| 고객 | 1 | 100K| 100K|00:00:00.06 | 457 | | | |
| 4 | INDEX FULL SCAN | PK_고 | 1 | 100K| 100K|00:00:00.02 | 209 | | | |
|* 5 | SORT JOIN | | 100K| 3 | 100K|00:00:00.09 | 3 | 2048 | 2048 | 2048 (0)|
| 6 | TABLE ACCESS FULL | 납입방| 1 | 3 | 3 |00:00:00.01 | 3 | | | |
----------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("B"."납입방법코드"="A"."납입방법코드")
filter("B"."납입방법코드"="A"."납입방법코드")
SQL> SELECT /*+ LEADING(A) USE_MERGE(B) */
2 a.납입방법, b.*
3 FROM 납입방법 a, 고객 b
4 WHERE b.납입방법코드 = a.납입방법코드
5 ;
...
SQL> @XPLAN
-----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 100K|00:00:00.11 | 255 | | | |
| 1 | MERGE JOIN | | 1 | 100K| 100K|00:00:00.11 | 255 | | | |
| 2 | SORT JOIN | | 1 | 3 | 3 |00:00:00.01 | 3 | 2048 | 2048 | 2048 (0)|
| 3 | TABLE ACCESS FULL| 납입 | 1 | 3 | 3 |00:00:00.01 | 3 | | | |
|* 4 | SORT JOIN | | 3 | 100K| 100K|00:00:00.09 | 252 | 3738K| 834K| 3322K (0)|
| 5 | TABLE ACCESS FULL| 고객 | 1 | 100K| 100K|00:00:00.02 | 252 | | | |
-----------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("B"."납입방법코드"="A"."납입방법코드")
filter("B"."납입방법코드"="A"."납입방법코드")
--INDEX
SELECT /*+ LEADING(A) INDEX( A PK_납입방법 ) USE_MERGE(B) */
a.납입방법, b.*
FROM 납입방법 a, 고객 b
WHERE b.납입방법코드 = a.납입방법코드
--------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 100K|00:00:00.13 | 258 | 1 | | | |
| 1 | MERGE JOIN | | 1 | 100K| 100K|00:00:00.13 | 258 | 1 | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| 납입방법| 1 | 3 | 3 |00:00:00.02 | 6 | 1 | | | |
| 3 | INDEX FULL SCAN | PK_납입 | 1 | 3 | 3 |00:00:00.02 | 3 | 1 | | | |
|* 4 | SORT JOIN | | 3 | 100K| 100K|00:00:00.08 | 252 | 0 | 3738K| 834K| 3322K (0)|
| 5 | TABLE ACCESS FULL | 고객 | 1 | 100K| 100K|00:00:00.02 | 252 | 0 | | | |
--------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("B"."납입방법코드"="A"."납입방법코드")
filter("B"."납입방법코드"="A"."납입방법코드")
SQL> SELECT /*+ LEADING(b) USE_HASH(a) */
2 a.납입방법, b.*
3 FROM 납입방법 a, 고객 b
4 WHERE b.납입방법코드 = a.납입방법코드
5 ;
@
...
SQL> @XPLAN
----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 100K|00:00:00.10 | 257 | | | |
|* 1 | HASH JOIN | | 1 | 100K| 100K|00:00:00.10 | 257 | 4544K| 1485K| 8969K (0)|
| 2 | TABLE ACCESS FULL| 고객 | 1 | 100K| 100K|00:00:00.02 | 252 | | | |
| 3 | TABLE ACCESS FULL| 납입 | 1 | 3 | 3 |00:00:00.01 | 5 | | | |
----------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("B"."납입방법코드"="A"."납입방법코드")
-- 카운터 방식
SELECT /*+ LEADING(b) USE_HASH(a) */
-- a.납입방법, b.*
COUNT(*)
FROM 납입방법 a, 고객 b
WHERE b.납입방법코드 = a.납입방법코드
;
--------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.27 | 205 | 198 | | | |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.27 | 205 | 198 | | | |
|* 2 | HASH JOIN | | 1 | 100K| 100K|00:00:00.26 | 205 | 198 | 3411K| 2022K| 7766K (0)|
| 3 | INDEX FAST FULL SCAN| IDX_2 | 1 | 100K| 100K|00:00:00.19 | 204 | 198 | | | |
| 4 | INDEX FULL SCAN | PK_납입 | 1 | 3 | 3 |00:00:00.01 | 1 | 0 | | | |
--------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("B"."납입방법코드"="A"."납입방법코드")
SQL> SELECT /*+ LEADING(A) USE_HASH(B) */
2 a.납입방법, b.*
3 FROM 납입방법 a, 고객 b
4 WHERE b.납입방법코드 = a.납입방법코드
5 ;
@
...
SQL> @XPLAN
----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 100K|00:00:00.11 | 6869 | | | |
|* 1 | HASH JOIN | | 1 | 100K| 100K|00:00:00.11 | 6869 | 1180K| 1180K| 608K (0)|
| 2 | TABLE ACCESS FULL| 납입 | 1 | 3 | 3 |00:00:00.01 | 3 | | | |
| 3 | TABLE ACCESS FULL| 고객 | 1 | 100K| 100K|00:00:00.04 | 6866 | | | |
----------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("B"."납입방법코드"="A"."납입방법코드")
--카운터방식
SELECT /*+ LEADING(A) USE_HASH(B) */
COUNT(*)
FROM 납입방법 a, 고객 b
WHERE b.납입방법코드 = a.납입방법코드
;
-----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.09 | 205 | | | |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.09 | 205 | | | |
|* 2 | HASH JOIN | | 1 | 100K| 100K|00:00:00.08 | 205 | 1517K| 1517K| 870K (0)|
| 3 | INDEX FULL SCAN | PK_납입 | 1 | 3 | 3 |00:00:00.01 | 1 | | | |
| 4 | INDEX FAST FULL SCAN| IDX_2 | 1 | 100K| 100K|00:00:00.02 | 204 | | | |
-----------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("B"."납입방법코드"="A"."납입방법코드")
--INDEX FFS
SELECT /*+ LEADING(A) USE_HASH(B) */
B.납입방법코드
FROM 납입방법 a, 고객 b
WHERE b.납입방법코드 = a.납입방법코드
----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 100K|00:00:00.10 | 6859 | | | |
|* 1 | HASH JOIN | | 1 | 100K| 100K|00:00:00.10 | 6859 | 1517K| 1517K| 890K (0)|
| 2 | INDEX FULL SCAN | PK_납입 | 1 | 3 | 3 |00:00:00.01 | 1 | | | |
| 3 | INDEX FAST FULL SCAN| IDX_2 | 1 | 100K| 100K|00:00:00.03 | 6858 | | | |
----------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("B"."납입방법코드"="A"."납입방법코드")
- 강좌 URL : http://www.gurubee.net/lecture/3269
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.