안녕하십니까?
대용량 테이블(6천만건 이상)의 인덱스 관련 질문드립니다.
이 테이블은 primary key와 noncluster 인덱스가 각각 1개씩 존재합니다. 그래서 테이블 조회시에
select *
from bigdata
where enc2 = '0000000123' 하면 순식간에 조회가 됩니다. 그런데 범위 조회를 하면 하세월입니다....
-- enc2는 인덱스가 걸린 필드입니다...
select *
from bigdata
where enc2 between '0000000123' and '0000000999' 이렇게 범위 조회를 하면 시간이 상당히 많이 걸립니다.
물론 인덱스 rebuild도 해 봤는데 마찬가지입니다. 그런데 인덱스 힌트를 주니 속도가 아주 잘 나옵니다.
-- 힌트 사용
select *
from bigdata with (nolock, index=idx_enc2)
where enc2 between '0000000123' and '0000000999'
왜 범위(between) 검색을 하면 인덱스를 타지 않는지 궁금하며, (힌트를 사용하지 않고) 인덱스를 태우는 방법을 알고 싶습니다.
Sql Server2005입니다.
감사합니다.
Comment 7
-
버뮤다삼각김밥
2013.02.25 12:51
-
쓸만한게없네(윤선식)
2013.02.25 13:56
아래 URL 참조요.
http://blogs.technet.com/b/mdegre/archive/2012/03/19/what-is-parameter-sniffing.aspx
아마 그 범위 내에 있는 것은 실행계획을 강제로 주면 잘 나오지면,
다른 범위에 있는 것들은 그렇지 않을 수 있습니다.
-
김시준
2013.02.25 15:41
제가 모르는 무엇을 하면 쉽게 될 줄 알았더니 그게 아니네요...
내부적으로 사용한다면 별 문제가 없겠지만 각각의 DB상황(버전, 테이블의 인덱스 등)이 다른 거래처에 자동으로 힌트를 구성해 준다는
것이 큰 문제가 될 것 같습니다...
버전이 올라가면(Sql Server2008이상) 저런 문제점들이 해결되 있을라나.....
고민되네요..
답변들 감사합니다...
-
방랑도사
2013.02.25 17:04
프로시저 에서 저 쿼리를 호출하고 조건을 바인딩변수로 받는건가요? 그렇다면 윤선식님이 지적한 파라미터 스니핑 문제일수도 있을듯 합니다.
그리고 확신이 없으시면 힌트는 안주도록 하는게 좋습니다. between 범위가 좁을땐 인덱스 타야좋지만 만약 힌트준 상황에서 범위가 넓게 오면 문제가 심각해지겠지요.
http://www.sqler.com/bColumn/372586
ULR에 나와있는 글을 보시면 도움이 될듯합니다.
-
김시준
2013.02.25 18:44
sp에서 바인딩 변수로 받을 수도 있고 그냥 동적으로 쿼리할 수도 있습니다. 상황 설명이 좀 애매합니다...
동적이든 sp든 상관없이 그냥 잘 됐으면 좋겠는데......
관련글을 잘 읽어 보도록 하겠습니다..
감사합니다.
-
버뮤다삼각김밥
2013.02.26 10:31
너무 신경쓰인다면 조건문을 줘서 상황에 따라 인덱스를 타게 해주는 방법을 쓰세요~^^
-
김시준
2013.02.26 11:46
예.. 버뮤다님.
감사합니다.
논 클러스터드 인덱스를 생성했는데 클러스터드 인덱스를 타는 경우일 듯 하네요.(실행계획보시면 아마도)
저도 그 문제때문에 고민 많이 했는데요. 결론은 옵티마이저의 판단이 항상 옳지 않기 때문에 힌트가 존재하는거겠죠.
힌트를 주지 않고 태우고 싶다면 보통 커버드 인덱스를 만들고요. 위 상황은 그러기 힘 들 것 같네요. 클러스터드 인덱스를 삭제하시면 되지만, 제가 생각하는 테이블 설계의 기본을 벗어나기 때문에 비추합니다.