개발을 하다보면 흔히 어떤 테이블에 원하는 데이터가 있는지 세어보는 경우가 가끔 있습니다. 이러한 경우 COUNT(*)를 사용하는데 좀더 빠르게 할 수 있는 방법이 있어 소개 드립니다.
COUNT를 할 때 전체 테이블을 FULL SCAN 할 수도 있고 INDEX 영역을 FULL SCAN할 수도 있습니다. TABLE을 전체 FULL SCAN 할 때와 INDEX영역을 FULL SCAN할 때 어디가 빠르다고는 장담하지 못합니다. 이러한 경우 테이블 이나 인덱스의 단일 블록을 SCAN하기 때문에 예측하기가 애매할 수 있는 것이죠... 만약 인덱스를 SCAN하는데 하나의 블록이 아니라 MULTI BLOCK을 SCAN한다면 어떨까요? 당연히 SINGLE BLOCK을 SCAN하는 것보다 빠를 수 있습니다. 이때 사용하는 것이 INDEX FAST SCAN이라는 것인데 COUNT하는 경우 당연히 속도가 빨라 집니다.힌트 INDEX_FFS를 이용하면 되는데 아래의 예를 참고하세요~
SQL)SELECT COUNT(*) FROM EMP;
Execution Plan
------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF ‘EMP’
SQL)SELECT /*+ INDEX(EMP pk_emp */ COUNT(*) FROM EMP;
Execution Plan
------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 INDEX FULL SCAN OF ‘pk_emp’ (UNIAUE) (cost=30)
---------------------------------------------
[아래처럼 인덱스 패스트 스캔을 이용하여 count 하세요]
---------------------------------------------
SQL)SELECT /*+ INDEX_FFS(EMP pk_emp) */ COUNT(*) FROM EMP;
Execution Plan
------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 INDEX (FAST FULL SCAN) OF ‘pk_emp’ (UNIQUE) (cost=2)
아래는 어떤 분이 50000건의 데이터로 간단히 인덱스를 이용하는것으로 count를 했을때의 결과라고
올려 놓은신건데 참고하세요...
-----------------------------------------------------------
힌트를 사용한 성능향상 테스트(http://cafe.naver.com/projectprogramming.cafe?frame_url=/ArticleRead.nhn%3Farticleid=118)
-----------------------------------------------------------
50000만 건을 입력하고 전체 카운터를 가져오는 테스트를 해보겠다.
여기서의 소요시간은 서버환경이나 측정하는 방법에 따라 달라 질 수 있다. 하지만 상대적으로 비교해 볼 수는 있는 것이니 어떤 효과가 있는지를 알기에는 충분하다고 생각한다.
1. select count(idx) idx from 테이블명
- 소요시간 : 203ms
2. select /*+ index(테이블명 인덱스명) */ count(idx) idx from 테이블명
- 소요시간 : 15ms
COUNT를 할 때 전체 테이블을 FULL SCAN 할 수도 있고 INDEX 영역을 FULL SCAN할 수도 있습니다. TABLE을 전체 FULL SCAN 할 때와 INDEX영역을 FULL SCAN할 때 어디가 빠르다고는 장담하지 못합니다. 이러한 경우 테이블 이나 인덱스의 단일 블록을 SCAN하기 때문에 예측하기가 애매할 수 있는 것이죠... 만약 인덱스를 SCAN하는데 하나의 블록이 아니라 MULTI BLOCK을 SCAN한다면 어떨까요? 당연히 SINGLE BLOCK을 SCAN하는 것보다 빠를 수 있습니다. 이때 사용하는 것이 INDEX FAST SCAN이라는 것인데 COUNT하는 경우 당연히 속도가 빨라 집니다.힌트 INDEX_FFS를 이용하면 되는데 아래의 예를 참고하세요~
SQL)SELECT COUNT(*) FROM EMP;
Execution Plan
------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF ‘EMP’
SQL)SELECT /*+ INDEX(EMP pk_emp */ COUNT(*) FROM EMP;
Execution Plan
------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 INDEX FULL SCAN OF ‘pk_emp’ (UNIAUE) (cost=30)
---------------------------------------------
[아래처럼 인덱스 패스트 스캔을 이용하여 count 하세요]
---------------------------------------------
SQL)SELECT /*+ INDEX_FFS(EMP pk_emp) */ COUNT(*) FROM EMP;
Execution Plan
------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 INDEX (FAST FULL SCAN) OF ‘pk_emp’ (UNIQUE) (cost=2)
아래는 어떤 분이 50000건의 데이터로 간단히 인덱스를 이용하는것으로 count를 했을때의 결과라고
올려 놓은신건데 참고하세요...
-----------------------------------------------------------
힌트를 사용한 성능향상 테스트(http://cafe.naver.com/projectprogramming.cafe?frame_url=/ArticleRead.nhn%3Farticleid=118)
-----------------------------------------------------------
50000만 건을 입력하고 전체 카운터를 가져오는 테스트를 해보겠다.
여기서의 소요시간은 서버환경이나 측정하는 방법에 따라 달라 질 수 있다. 하지만 상대적으로 비교해 볼 수는 있는 것이니 어떤 효과가 있는지를 알기에는 충분하다고 생각한다.
1. select count(idx) idx from 테이블명
- 소요시간 : 203ms
2. select /*+ index(테이블명 인덱스명) */ count(idx) idx from 테이블명
- 소요시간 : 15ms
'DB' 카테고리의 다른 글
[대용량데이터베이스] 조인의 최적화 (0) | 2006.07.20 |
---|---|
SQL로 들어가서 XML로 나온다 (0) | 2006.07.16 |
[QUERY] index rebuild 예 (0) | 2006.07.16 |
[QUERY] 실행중인(ACTIVE) SQL문 확인 (0) | 2006.07.16 |
[QUERY] Role (0) | 2006.07.16 |