SQL Server 에서 index merge 유도하기


http://merritt.co.kr/tt/73 에서 인덱스 머지에 관한 기초적인 이야기를 썼는데, 1억건이 넘어가는 엄청나게 큰 테이블들에 조회조건이 굉장히 다양하게 들어올 때 인덱스 구조를 잡는 것이 상당한 고민이 된다.

이때 인덱스 머지 전략을 적절하게 사용하면 인덱스 길이를 최소화하면서 성능도 그렇게 떨어지지 않는 쿼리를 만들어낼 수 있다. 그러면 인덱스 머지를 어떻게 유도할 것이냐가 문제다. 대부분의 경우 서버가 알아서 실행계획을 세워준다지만, 힌트를 줘서 유도할 수 있으면 싶을 때도 있다.

SQL 서버에는 인덱스 머지라는 힌트는 없지만, index 를 여러개 지정함으로써 인덱스 머지 플랜을 유도할 수 있다. 자세한 것은 SELECT 문에 대한 BOL 의 설명을 자세히 읽어보면 된다.

select * from table1 a with(index(ix_1, ix_2) where col1 = 'A' and col2 = 2

이렇게 하면 ix_1 과 ix_2 를 각각 읽어서 clustered index key 를 이용한 join 을 수행하게 된다. 컬럼의 분포도와 선택성을 고려해서 여러가지로 테스트해보면 이런 전략이 유용할 때가 있다.

Posted by maceo

12 18, 2006 11:13 12 18, 2006 11:13
, , , ,
Response
No Trackback , No Comment
RSS :
http://merritt.co.kr/tt/rss/response/83

길다란 복합 인덱스가 능사가 아니다?


작성: 박노철(maceo.park@gmail.com)


오늘 기존 테이블에 대한 index tuning 을 하다가 발견한 현상.

테이블 T1 사이즈 : 1500만건
T1에는 클러스터드 인덱스가 있다고 가정하자.

select * from T1 where a = 1 and b = 1 and c = 1 and d = 1

이라는 쿼리가 있다고 치자. 이럴때는 보통

create index idx__a_b_c_d on T1 (a,b,c,d)

이렇게 잡는다.

그런데 다음 쿼리가 들어왔다.

select * from T1 where c = 1 and d = 1

그러면 c,d 에
create index idx__c_d on T1 (c,d)

복합인덱스를 잡으면 된다.

이제 우리는 a,b,c,d 와 c,d 에 대한 인덱스 두개를 가지고 있다. 일반적으로 위와 같이 해결 하지만 다른 방법도 생각해볼 수 있다. where조건을 구성하는 컬럼을 분해해서 다음과 같이 인덱스를 구성하는 것이다.

create index idx__a_b on T1 (a,b)
create index idx__c_d on T1 (c,d)

좀 이상하지 않은가?????

이렇게 하면 where a=1 & b=1 & c=1 & d=1 에 대해서 idx__a_b를 타게 될테니 idx__a_b_c_d가 있을 때보다 읽기수가 대폭 증가할 것이라고 예상이 된다. idx__a_b를 탄 후에 bookmark lookup 을 해서 c,d를 체크해야 할 테니. 하지만 이런 경우 SQL Server는 똑똑하게 동작한다. 옵티마이저는 bookmark lookup 의 비용이 과도하다고 판단하면 T1의 두개의 인덱스 idx__a_b와 idx__c_d를 동시에 Index Seek을 해서 join 을 해버린다. maxdop 가 높고 시스템 가용자원이 남아서 병렬 계획을 수립할 가능성이 높으면 더더욱 두개의 인덱스를 병렬로 seek하는 방향으로 실행계획이 유도된다. join 할 때는 각각의 인덱스 끝에 붙어 있는 클러스터드 인덱스 키를 이용하는 것 같다. a,b의 선택성이 좋아서 bookmark lookup 비용이 과도하지 않으면 저렇게 동작하지 않는 것 같다.

인덱스를 위와 같이 잡을 때의 이점은 명백하다. c,d 컬럼에 대해서 중복 인덱스를 잡을 필요가 없어진다. 그렇다고 해서 idx__a_b_c_d가 있을 때보다 읽기수가 엄청나게 증가하는 것은 아니다. 물론 늘어나긴 하지만 감당할만한 수준이다.


결론: 액세스가 빈번하지는 않으나 테이블 사이즈가 매우 커서 공간을 절약할 필요가 있는 경우 where조건을 구성하는 컬럼을 분해해서 각각의 index를 잡는 전략을 고려해볼 수 있다.

Posted by maceo

09 28, 2006 17:36 09 28, 2006 17:36
, ,
Response
No Trackback , a comment
RSS :
http://merritt.co.kr/tt/rss/response/73


블로그 이미지

가늘어도 긴놈이 장땡

- maceo

Archives

Authors

  1. maceo

Calendar

«   3 2010   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      

Site Stats

Total hits:
170306
Today:
4
Yesterday:
46