얼마전 고객사 DB를 튜닝하다가 생긴 일이다.

TEST_TAB 테이블에는 26만건의 데이터가 들어 있다.

SET STATISTICS IO ON
SET STATISTICS TIME ON


SELECT MAX(SEQ) + 1 FROM TEST_TAB


INDEX가 없을 때, 위의 SQL을 실행시켰을 때의 IO와 실행시간을 측정하면 다음과 같다.

(1개 행 적용됨)

Table 'TEST_TAB'. Scan count 1, logical reads 713, physical reads 0, read-ahead reads 0.

SQL Server Execution Times:
   CPU time = 297 ms,  elapsed time = 301 ms.


이 SQL이 바로 고객사 DB서버 CPU를 100%치게 만든 악성 SQL 세 개 중 하나였다.
물론, 실행되는 빈도가 높지 않다면 별 문제가 안되겠지만, 이런 SQL이 문제가 되는 것은 무조건 Table Full Scan을 하기 때문에 DATA가 쌓일 수록 영향이 커진다는 것이다.

해결책은 간단하다. SEQ 컬럼에 INDEX를 친 후 다시 한번 실행하면 다음과 같다.

Table 'TEST_TAB'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0.

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.


 COUNT함수도 마찬가지다.

SELECT COUNT(*) FROM TEST_TAB WHERE MANAGE = 1



위의 SQL을 실행시켰을 때의 부하는 다음과 같다.

Table 'TEST_TAB'. Scan count 1, logical reads 713, physical reads 0, read-ahead reads 136.

SQL Server Execution Times:
   CPU time = 63 ms,  elapsed time = 143 ms.



MANAGE 컬럼에 인덱스를 친 후엔 다음과 같이 된다.

Table 'TEST_TAB'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0.

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.



결론은 이거다.

실행 빈도가 비교적 높은 SQL에서 Group함수를
사용해야 할 경우, 반드시 인덱스를 고려하라


 

Posted by kuaaan

댓글을 달아 주세요

  1. kuaaan 2008.08.21 21:13 신고  댓글주소  수정/삭제  댓글쓰기

    당연한 이야기이지만... 실행계획을 보았을 때 인덱스를 타는 경우에만 효과가 있다. 선택도가 나빠서 (결과 RecordSet의 수가 많아서) 인덱스를 타지 못하는 경우는 인덱스가 효과가 없다.



사랑합니다. 편안히 잠드소서