권순용의 DB 이야기
변형된 인덱스 실행 계획을 이해하자 1 1 99,999+

by axiom SQL 최적화 실행계획 Index Fast Full Scan [2013.02.18]


인덱스 실행 계획은 매우 다양하다. 인덱스 실행 계획이 다양하다는 것은 무엇을 의미하는가? 인덱스 관련 실행 계획이 다양하다는 것은 인덱스를 이용하는 SQL의 실행될 수 있는 방법이 다양하다는 의미일 것이다.

이와 같다면 인덱스를 이용하는 SQL은 여러 가지의 시행 계획을 도출할 수 있고 이 중 어떤 실행 계획을 생성하는가에 따라 수행 속도는 천차만별이 될 것이다. 이와 같은 이유에서 인덱스를 액세스하는 실행 계획을 정확히 이해해야 할 것이다.

인덱스 실행 계획은 매우 다양하다. 우리가 원하는 범위만을 인덱스를 이용해 액세스할 수도 있지만 인덱스를 처음부터 끝까지 액세스할 수 있고 또한 인덱스 여러 개를 조합해 원하는 결과를 추출할 수 있다.

이와 같이 인덱스 관련 실행 계획이 다양하기 때문에 인덱스 실행 계획을 정확히 파악하는 것은 매우 중요하다. 이번 강의에서는 인덱스를 전체 액세스하는 방법 중 인덱스 Fast Full Scan을 확인해 보자.

인덱스는 Fast Full Scan이 가능하다

인덱스 Fast Full Scan은 무엇인가? 지난 호에서 인덱스 Full Scan에 대해 확인해 보았다. 인덱스 Full Scan은 어떠하였는가?

인덱스 Full Scan은 인덱스를 처음부터 끝까지 액세스하는 경우이다. 그렇기 때문에 잘못하면 처리 범위가 증가할 수 있는 형태이다. 지난 강의에 언급했던 예제를 확인해 보자.

SELECT COL1, COL2
  FROM TAB1
 WHERE COL3 = 'AAA'
 ORDER BY COL4

위의 예제에서 TAB1 테이블에는 COL4+COL3 인덱스가 존재한다면 어떻게 되었는가?

이와 같은 경우에 해당 SQL이 인덱스를 이용한다면 해당 SQL은 인덱스를 통해 처리 범위를 감소 시킬 수 없기 때문에 인덱스를 처음부터 액세스하는 인덱스 전체스캔을 수행하게 될 것이다. 하지만 인덱스 Full Scan은 인덱스 블록을 하나하나 액세스하는 단일 블록 I/O를 발생시키게 된다.

인덱스를 처음부터 끝까지 읽어야 한다면 굳이 단일 블록 I/O를 수행해야 하는 것인가? 그것은 아닐 것이다. 인덱스를 처음부터 끝까지 액세스해야 한다면 인덱스 블록은 한 번에 여러 개씩 액세스하는 다중 블록 I/O를 수행하는 것이 성능에 더 유리할 것이다.

결국 인덱스 Fast Full Scan은 인덱스 Full Scan이 인덱스 블록을 액세스하는 과정에서 다중 블록 I/O 방식으로 액세스하여 액세스 성능을 향상시키는 방식을 의미한다.

인덱스는 Fast Full Scan vs. 인덱스 Full Scan

앞서 인덱스 Full Scan은 단일 블록 I/O를 수행하고 인덱스 Fast Full Scan은 다중 블록 I/O를 수행한다고 했다. 과연 인덱스 Fast Full Scan과 인덱스 Full Scan은 이 차이밖에는 없는것일까?

일반적으로 단일 블록 I/O를 수행하는 것보다는 다중 블록 I/O를 수행하는 것이 더 유리하므로 무조건 인덱스 Fast Full Scan이 좋은 실행 계획이 되는 것인가? 그렇지 않다면 또다른 무슨 차이가 있는 것인가?

중요한 점은 인덱스 Fast Full Scan과 인덱스 Full Scan은 이와 같은 단일 블록 I/O와 다중 블록 I/O에서 시작한다는 것이다.

첫 번째로 정렬된 데이터이다. 인덱스 Full Scan은 인덱스를 처음부터 블록을 하나하나씩 액세스하기 때문에 인덱스의 첫 번 째 컬럼으로 정렬된 데이터가 추출된다.

물론 인덱스의 첫 번째 컬럼의 값이 동일한 데이터에 대해서는 인덱스의 두 번째 컬럼에 의해 정렬된 데이터가 추출된다. 이는 인덱스 블록을 하나하나씩 액세스하기 때문이다.

하지만 인덱스 Fast Full Scan은 인덱스 블록을 하나하나씩 액세스하는 것이 아니며 한번에 여러 인덱스 블록을 액세스해야 하므로 인덱스의 첫 번째 컬럼에 의해 정렬된 데이터가 추출되지 않게 된다.

이는 SQL을 최적화하는 과정에서 매우 중요한 요소가 될 수 있다. 하나의 예제를 확인해 보자.

SELECT COL1, COL2
  FROM TAB1
 WHERE COL3 = 'AAA'
 ORDER BY COL4

위 SQL은 COL4+COL3 인덱스를 이용한다고 가정하자. 그렇다면 인덱스 Full Scan 또는 인덱스 Fast Full Scan을 이용하게 된다.

인덱스 Full Scan은 COL4 컬럼에 의해 자동 정렬된 데이터가 추출되므로 실행 계획에는 Sort 실행 계획이 생성되지 않을 것이다.

하지만 인덱스 Fast Full Scan은 COL4 컬럼으로 정렬된 데이터가 추출되지 않으므로 실행 계획에는 Sort 실행 계획이 생성된다.

두 번째는 병렬 프로세싱이다. 병렬 프로세싱은 하나의 작업을 여러 개의 프로세스로 나뉘어 작업하는 것을 의미한다.

이와 같은 방식은 대용량의 데이터를 액세스하는 과정에서 매우 효과적인 방식이다. 그렇기 때문에 대용량 데이터베이스를 최적화하는 과정에서 많이 사용될 수 있다.

인덱스를 액세스하는 과정에서도 이와 같은 병렬 프로세싱을 사용할 수 있다. 하지만 병렬 프로세싱은 다중 블록 I/O를 수행하는 경우에만 가능하다. 그렇기 때문에 인덱스 Fast Full Scan만이 병렬 프로세싱이 가능하게 된다.

결국 인덱스 Full Scan과 인덱스 Fast Full Scan은 아래와 같은 차이를 가지게 되며 이는 단일 블록 I/O를 수행하는지 아니면 다중 블록 I/O를 수행하는지의 차이에 의해 발생하게 된다.

  • - 인덱스 Fast Full Scan은 인덱스에 의해 정렬된 데이터가 추출되지 않는다.
  • - 인덱스 Fast Full Scan은 병렬 프로세싱이 가능하다.

인덱스 Fast Full Scan을 효과적으로 이용하자

인덱스 Fast Full Scan은 어떤 경우에 유리한 것인가? 이는 인덱스 Fast Full Scan이 어떤 특징을 가지는지를 정확히 이해 한다면 어려운 일이 아닐 것이다.

  • - 인덱스로만 원하는 데이터를 모두 추출하는 경우
  • - 해당 테이블의 데이터 중 대부분을 추출하는 경우
  • - 정렬이 불필요한 경우

위와 같이 세 가지 조건을 모두 만족해야만 인덱스 Fast Full Scan이 의미 있게 된다. 그러므로 인덱스만으로 해당 테이블의 데이터를 대부분 추출하며 정렬이 불필요한 경우에 인덱스 Fast Full Scan을 이용하면 효과적으로 이용할 수 있게 된다.

예를 들어 보자.

SELECT COUNT(*)
  FROM TAB1

위의 SQL은 TAB1 테이블의 데이터 건수를 확인하는 SQL이 된다. 보통 개발을 하다 보면 테이블의 데이터의 건수를 확인해야 하는 경우가 종종 발생하게 된다.

이와 같은 경우는 어떤 경우인가? 위의 SQL은 TBA1 테이블의 PK를 이용하면 테이블 액세스 없이 원하는 값을 추출할 수있을 것이다.

이는 모든 테이블은 PK가 존재해야 하며 PK는 해 당 테이블의 모든 데이터를 저장하고 있다. 그렇기 때문에 PK의 건수를 확인하는 것으로 우리는 테이블의 데이터 건수를 확인할 수 있게 된다.

이런 경우 인덱스만 액세스해 원하는 데이터를 추출할 수 있으며 해당 데이터의 데이터를 모두 액세스해야 총 건 수를 확인할 수 있으므로 해당 테이블의 데이터 중 대부분을 추출하는 경우에 해당한다.

또한 COUNT는 정렬을 수행하지 않게 되므로 이는 인덱스 Fast Full Scan으로 효과를 극대화할 수 있게 된다.

이처럼 인덱스 Fast Full Scan은 몇 가지 경우에 매우 유용하 게 사용할 수 있는 아키텍처를 가지고 있다. 우리가 정확한 이해 를 통해 효과적으로 사용한다면, 이러한 하나하나가 SQL 최적 화를 위한 무기가 될 수 있다.

다음 강의에서는 인덱스 스킵 스캔과 인덱스 MIN/MAX 실행에 대해 같이 확인해 보도록 하겠다.

- 강좌 URL : http://www.gurubee.net/lecture/2256

- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^

- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.

by 참된신자 [2014.08.01 09:26:12]

감사합니다 :)

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입