2016년 12월 13일 화요일

[오라클교육,튜닝교육,SQL교육학원추천_탑크리에듀][SQL,COUNT]분포도가 좋지않은 컬럼(B*Tree인덱스)의 count연산시 index fast full scan과 index range scan의 성능 차이 비교

[SQL,COUNT]분포도가 좋지않은 컬럼(B*Tree인덱스)의 count연산시 index fast full scan과 index range scan의 성능 차이 비교 

아래 테스트를 보시면 알겠지만 비트리 인덱스인 경우 분포도가 좋지 않은 컬럼을 count하는 경우라면 
index fast full scan보다 index range scan이 좋을 것 같습니다. 

아래 결과 확인해 주세요~ 

myemp1 테이블의 성별(sungbyul) 칼럼은 'M' or 'F' 값을 가지며 값의 분포도는 50% 이다. 

desc myemp1 
이름      널        유형            
-------- -------- ------------- 
EMPNO    NOT NULL NUMBER        
ENAME            VARCHAR2(100) 
DEPTNO            VARCHAR2(1)  
ADDR              VARCHAR2(100) 
SAL              NUMBER        
SUNGBYUL          VARCHAR2(1) 

-- 비트리 인덱스를 만들자. 
create index idx_myemp1_sungbyul on myemp1(SUNGBYUL) 

1. CBO MODE에서 COUNT를 하면 기본적으로 index fast full 스캔을 한다. 
(수행시간 : 2초) 

SQL> alter session set optimizer_mode = all_rows; 

SQL> select count(*) from myemp1 where sungbyul = 'M'; 

  COUNT(*) 
---------- 
  12000000 

경  과: 00:00:02.03 

Execution Plan 
---------------------------------------------------------- 
Plan hash value: 977383106 
---------------------------------------------------------- 
| Id  | Operation            | Name                | Rows  | Bytes | Cost (%CPU 
-------------------------------------------------------------------------------- 
|  0 | SELECT STATEMENT      |                    |    1 |    2 |  9995  (2 
|  1 |  SORT AGGREGATE      |                    |    1 |    2 | 
|*  2 |  INDEX FAST FULL SCAN| IDX_MYEMP1_SUNGBYUL |    10M|    19M|  9995  (2 
-------------------------------------------------------------------------------- 


2. RBO MODE에서 COUNT를 하면 기본적으로 index range 스캔을 한다. 
(수행시간 : 0초) 

SQL> alter session set optimizer_mode = rule; 
SQL> select count(*) from myemp1 where sungbyul = 'M'; 

  COUNT(*) 
---------- 
  12000000 

경  과: 00:00:00.70 

Execution Plan 
---------------------------------------------------------- 
Plan hash value: 1101074595 

------------------------------------------------- 
| Id  | Operation        | Name                | 
------------------------------------------------- 
|  0 | SELECT STATEMENT  |                    | 
|  1 |  SORT AGGREGATE  |                    | 
|*  2 |  INDEX RANGE SCAN| IDX_MYEMP1_SUNGBYUL | 
-------------------------------------------- 


3. 아래처럼 CBO 모드라면 index 힌트를 사용해도 된다. 

SQL> select /*+ index(myemp1 idx_myemp1_sungbyul) */  count(*) from myemp1 where sungbyul = 'M'; 

  COUNT(*) 
---------- 
  10000002 

경  과: 00:00:00.75 

Execution Plan 
---------------------------------------------------------- 
|  0 | SELECT STATEMENT  |                    |    1 |    1 | 18223  (1)| 0 
|  1 |  SORT AGGREGATE  |                    |    1 |    1 |            | 
|*  2 |  INDEX RANGE SCAN| IDX_MYEMP1_SUNGBYUL |    10M|  9765K| 18223  (1)| 0

댓글 없음:

댓글 쓰기