안녕하세요. DB 초보라 혼자 공부하다 보니 너무 어려워 고수님들 도움을 청합니다.^^
일단 제가 궁금 한건 선택도에 관한 것 입니다.
제가 알고 있는 것은,
1. 컬럼에 nonclustered index 를 생성할 경우, 선택도가 좋은 컬럼에 index를 만들어야 한다.
2. 선택도 좋은지를 알 수 있는 방법은 통계를 보면 된다.
3. 해당 컬럼의 통계를 보는 방법중 하나는 dbcc show_statistics(table_name, index_name)
으로 알고 있습니다.
그럼, dbcc show_statistics 를 실행 했을 경우,
* 결과 데이터 중 어떤 것을 보고 선택도를 알 수 있는지 궁금 합니다.
제가 알고 있는 것은,
. 밀도(density) = 1 / distinct value 개수
. 선택도(Selectivity) = 찾을 데이터 / 전체 행 수
인데,
ㄱ. all density 컬럼에 나온 값이 선택도 인가요?
검색을 해보니 all density 가 선택도 라고도 하고, 밀도 라고도 하고... 어떤것이 맞는거죠?
ㄴ. 만약 all density 가 밀도라면 show_statistics(table_name, index_name) 실행 후 결과를 보고
'해당 컬럼이 선택도가 좋다' 라는 것을 어떻게 판단해야 하나요?
- 어떤 웹페이지에서는 '선택도가 0.43% 이하(table 마다 다를 수 있음) 일 경우, 인덱스를 걸어도 좋다..' 라고 하는데
all density 가 밀도라면, 선택도를 show_statistics 실행 후 결과를 보고 어떻게 계산 해야 하는 것인가요?
정말 헷갈리네요..
고수님들의 자세한 조언 부탁 드립니다.
꾸벅.
Comment 10
-
항해자™
2013.05.25 21:55
-
zamta
2013.05.26 00:25
일단 답변 달아 주셔서 감사합니다.
그런데.. 제가 질문한것에 대한 답변이 아닌것 같은데요.... ;;
제가 궁금한 것은 all density 에 나온 값을 선택도 or 밀도 어느 것으로 봐야 하는 것인가? 와
show_statistics 를 실행 했을 경우, 어떤것을 보고 선택도가 좋은지를 알 수 있냐는 것 입니다.
위질문한 것에 대해 다시 한번 답변 부탁 드립니다.
감사합니다.
-
처리짱
2013.05.27 17:42
dbcc show_statistics 했을때 두번째 나오는 값을 분포도 세번째 값을 밀도라 부르지 않나요;
ㄱ. 분포도는 별로 중요하지 않습니다. 밀도(3번째 select값) 가 중요함.
ㄴ. 밀도 쿼리(3번째)를 보면은 RANGE_ROWS 와 EQ_ROWS 가 있는데요.
RANGE_HI_KEY가 인덱스 컬럼의 값이죠.. 인덱스 걸떄 첫번째 컬럼이 제일 중요한 이유가 바로 요기에 있어요.
EQ_ROWS 는 RANGE_HI_KEY(실제값)의 갯수이고 , RANGE_ROWS는 위 행과 사이에 있는 값의 갯수인데요.
0.43프로 이하면 인덱스를 탄다고 하는데 정확한 값은 아니고요.. 데이터 양이 많아 질수로 수치가 계속 작어집니다..
WHERE A = 1 과 같은 쿼리 보면은 RANGE_HI_KEY에서 값을 찾아 EQ_ROWS에 값이 총 로우 0.43%이하에 들면 인덱스를 제대로 타겠죠.. WHERE A < 10 과 같은 쿼리는 RANGE_HI_KEY에서 값을 찾아 EQ_ROWS에 값이랑 10보다 작은 위의 RANGE_ROWS의 값을 모두더해서 0.43%이하에 드는지는 확인하면 됩니다..
WHERE A BEWTEEN 10 AND 1000 과같은 쿼리를 자주 사용하는데 RANGE_HI_KEY, EQ_ROWS 더한값이 1%로 이상이면 다른 컬럼을 인덱스로 고려해 봐야겠죠..
0.43% 저거는 정확한 수치가 아니에요~
-
minsouk
2013.05.27 21:55
ㄱ. all density 컬럼에 나온 값이 선택도 인가요?
검색을 해보니 all density 가 선택도 라고도 하고, 밀도 라고도 하고... 어떤것이 맞는거죠?all density = 전체 밀도 입니다.
ㄴ. 만약 all density 가 밀도라면 show_statistics(table_name, index_name) 실행 후 결과를 보고
'해당 컬럼이 선택도가 좋다' 라는 것을 어떻게 판단해야 하나요?- 어떤 웹페이지에서는 '선택도가 0.43% 이하(table 마다 다를 수 있음) 일 경우, 인덱스를 걸어도 좋다..' 라고 하는데
all density 가 밀도라면, 선택도를 show_statistics 실행 후 결과를 보고 어떻게 계산 해야 하는 것인가요?all density 는 컬럼 전체의 밀도 즉 이것은 평균적인 밀도이며, 쿼리가 바인드변수 피킹이나, 파라메터 스니핑을 하지 못할 때 사용되는 밀도 입니다. 반면, 바인드변수 피킹이나 파라미터 스니핑이 가능한 상황이라면, histogram 을 이용하게 됩니다. 둘 중 어떤것을 이용 했으냐에 따라 내 쿼리의 선택도 판단은 달라 집니다. 데이터 선택도는 둘 중 무엇을 사용하고 내가 쿼리하는 데이터가 뭐냐에 따라 틀립니다.
간단한 예를들어 봅시다.
밀도가 1에 가까워 지면 거의다 같은 데이터 이고, 밀도가 0에 가까워지면 전체 행에 같은 행이 거의 없다는 말입니다.
만약 밀도가 1이면, 모두 같은데이터이고, 밀도가 0.1 이고 전체행수가 10 이라면 같은 데이터가 (0.1 * 10) 1개 있다는 말입니다.
선택도가 0에 가까운 것이 밀도는 낮고 선택도는 좋다는 말입니다.
자 그럼 histogram 에는 밀도처럼 보이는게 없는데 어떻게 하느냐? 여기는 수학의 힘을 이용해 최대 200개 단계값만을 이용해 효과적으로 개별 값의 선택도를 계산가능하게 표현하고 있습니다. 이때는 전체 행수 (1번째 단락에 있는 값) 과 histogram 의 값을 이용해 SQL Server 가 내부적으로 계산해 사용 합니다.
내 데이터는 전체 행수는 10개, 이중 distinct 한 값이 3개 1,1,1,1,1, 1,1,1,2,3 의 값을 갖는다고 봅시다.
all densitiry = 1/NDV = 0.3333333 입니다.
histogram 은
RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
1 0 8 0 1
3 1 1 1 1로 단 2개의 행으로 전체 통계를 잘 표현 합니다.
첫 번째 파라메터 바인딩을 못하는 쿼리이고 0.333333 은 선택도가 좋아 보입니다. 그런데, 1을 쿼리하면 nc 의 값을 이용해 원본데이터를 확인해 오기위해 8번 룩업을 해야 합니다. 이때는 clustered index 를 full scan 하는게 유리 합니다.
두 번째 파라메터 바인딩을 할 수 있고 3을 predicate 의 조건자로 주었다. 그럼 3과 같은행이 1건 이므로, index 가 있는게 유리 합니다.
인덱스로 한건 btree 탐색을 하고 clustered index 를 한건 join (lookup) 해는게 유리 하잖아요
질문을 죽 보니, 질문 하신분은 개념은 정확히 이해하고 있고, SQL 이 경우에 따라 all density 를 쓰는지 histogram 을 쓰는지 이해하지 못해 혼란이 있는듯 합니다. 위 예는 좀 그시기 한 면도 있습니다. 원래 값을 더 많이 넣고 데이터를 더 스큐되게 표현하고 억세스패턴을 어떻게 힌트로 고정시키느냐 등도 설명해야 하는데, 그까지 온라인에 한 아티클에 적기에는 좀 지면이 부족하군요
조금 더 이해하실려면, 영진출판사의 "db 성능 향상을 위한 sql server 운영과 튜닝" SQLTAG.ORG 지음 이라는 책을 차근 차근 읽어보는 것도 좋은 방법 입니다.
더불어 좀 더 깊이 생각한 사람들도 있는데요, 다음 아티클은 위 내용을 다 이해하고 한번 봐주세요 ~
http://sqlsql.tistory.com/186 글 중 Scan Tipping Point 링크를 한번 보는것도 재미있는 시간일듯 합니다.
혹시 부족하거나 더 설명을 듣고 싶으시면 스터디에 참가하는 것도 좋습니다.
감사합니다.
-
jevida(강성욱)
2013.05.27 22:26
-
Alucard(강산아)
2013.05.27 22:06
질문도 예쁘고 답변도 예쁘네요... 제 점수는요...
-
minsouk
2013.05.27 22:20
.
-
쓸만한게없네(윤선식)
2013.05.27 22:21
YSS에서는 minsouk 을 캐스팅하겠습니다.
-
zamta
2013.05.28 10:57
자세한 답변 정말 감사 드립니다.
제가 초보라서 그런지, 답변을 보니 더 헷갈리네요.ㅎ
답변 내용을 요약하면,
쿼리하는 데이터가 무엇이냐에 따라, 'all density를 사용할 것인지, histogram을 사용할 것인지 옵티마이저가 결정한다.'
인것 같은데 맞습니까?
그럼, 제가 만약에 DBA 라면
테이블내 특정 컬럼에 index를 잡는것이 좋은 것인가?(해당 컬럼이 선택도가 좋은가?)
를 판단하려면 어떻게 해야 되는지.. 솔직히 많이 헷갈리네요.
위에 설명하신 부분을 모두 고려해서 해야 되는 것 같은데...
답변을 읽어보면 읽어볼수록.. 어렵네요 ;;
어떻게 간단하게 판단할 수 있는(기본적으로 사용되는) 방법이 없을까요??
인덱스를 설정하는 게 좋다.. 라는 것을 어떻게 판단을 해야 하는지.. ^^;;
언급하신 책을 한번 사서 보도록 하겠습니다.
하나 더, 스터디는 어디서, 어떻게 알아보고 해야 될까요?
좋은 스터디가 있다면, 하나 추천 해 주시겠습니까? 아니면 site url 이라도..
offline 스터디 도 상관없습니다.
바쁘신데, 자꾸 질문 드려 죄송합니다.
한번만 더 답변 부탁 드립니다.(ㅡㅡ)(__)
-
minsouk
2013.05.28 13:06
네.....제가 좀 설명을 모호하게 했나 봅니다.
나중에 스터디에서 뵙겠습니다.
스터디 URL = http://sqltag.org
이번스터디 = http://cafe.naver.com/sqlmvp/3845
참석하시면 이거 알려주세요~ 라고 마이크로 말하세요. 다시 도전해 보겠습니다. ^^;;
선택도 즉, NDV(Number of Distinct Value)가 높은 것을 의미합니다,,,
unique 컬럼이라면 선택도가 매우 좋은 것 이죠,,
반대로 성별 같은 컬럼은 선택도가 나쁜 컬럼입니다,,
두개 중 하나를 선택해야 하는 상황이면 인덱스를 뒤지느니 풀스캔하는게 훨신 낫겠죠??
반대로 하나 밖에 없거나 조회하려는 값이 unique하거나 ROWCOUNT가 적으면 인덱스를 보고 찾아가는게 큰 도움이 되죠,,,