mssql 인덱스 관련질문 0 2 1,044

by 티라미수꿀맛 [SQLServer] [2020.02.04 01:16:50]


안녕하세요

mssql 인덱스 관련질문드리려합니다.

궁금한게 인덱스 스캔을 타는 상황에 대해 이해가 안되는게 있습니다.

남자 ,여자 성별이 들어있는 컬럼에 인덱스를 걸었다고 치면

남자가 백만건,여자가 백만건이 들어있다고 치고 그러면 데이터가 많지만 종류가 적어 

인덱스를 쓸필요가없다 라는 말이 이해가안되는데요

제가 생각한건 인덱스란건 검색을 할때 자기가 원하는 데이터까지만 찾고 그 이상의 탐색은 안하는걸로 알고있는데 테이블 풀스캔은 원하는 데이터를 찾아도 끝까지 탐색을 하는걸로 알고있습니다.

여기서 생각해본게 만약에 where 에 남자를 찾는다 라고친다면 인덱스가 걸려있지않다면 풀스캔을해서 200만건을 찾아야하는데

인덱스가 걸려있을때는 백만건의 남자만 찾고 그 이상의 탐색은 안하니 훨씬 더 효율적인거 아닌가요?

왜 인덱스를 쓰는게 더 비효율적인건가요?

어디서 제가 잘못된 지식을 가지고 있는지 헷갈립니다. 좋은 답변 부탁드립니다. ㅠ.ㅠ

by jkson [2020.02.04 07:51:38]

성별인덱스

성별 ROWID
1
3
5
2
4

 

테이블

ROWID 성별 이름
1 홍길동
2 홍길녀
3 김유신
4 신사임당
5 김정호

성별인덱스와 테이블입니다.

인덱스에 SELECT절 FROM 절등에 사용한 컬럼이 모두 있다면 테이블을 읽을 필요가 없습니다만 인덱스에 모든 정보가 없다보니 테이블을 읽어야 합니다.

(위 예에서 SELECT 절이나 FROM 절에 '이름' 컬럼을 사용했다면..)

인덱스를 통해 테이블에 접근하려면 인덱스 한 건을 읽고 테이블 한 건을 읽고 그 다음 인덱스 한 건을 읽고 다시 테이블 한 건을 읽는 식으로 데이터를 패치해야합니다.

여기서 남자만 SELECT하면 ROWID 1->3->5 순으로 조회가 되는데요.

인덱스와 테이블을 왔다갔다하면서 확인하는 것입니다.(랜덤액세스)

이렇게 왔다갔다 하는 건수가 작다면 효율적이겠지만

대용량 테이블에서 테이블 절반 가량의 데이터를 이렇게 왔다가갔다 찾는 것보다는

그냥 테이블 첨부터 끝까지 순차적으로 읽어서 필요한 데이터만 필터하는 것이 효율적인 게 되는 것이죠.


by 메뚝 [2020.02.04 14:07:53]

mssql 을 질문하셨지만 참고로 oracle 의 경우

index scan 과 full scan 은 I/O 방식이 다릅니다.

index scan : Single Block I/O  (1번에 1개의 Block 을 엑세스)

full scan : Multi Block I/O (1번에 여러개의 Block 을 엑세스) (예: 128 / 설정값 조절가능)

* Block = mssql의 Page 와 같은 개념

즉, 인덱스 스캔을 할때는 1번에 1개의 Block 만 가져오지만 풀스캔할떄는 한번에 여러개의 Block 을 가져옵니다.

(물론 Single block I/O 와 Multi block I/O 의 속도 차이는 있습니다.  당연히 Single 이 좀 더 빠름)

 

성능개선(튜닝)을 할때 I/O 횟수를 줄이는게 중요한데

결과건수가 많을수록 (윗분이 설명하신것처럼) 인덱스를 사용하는것보다 풀스캔이 더 유리한 경우가 발생합니다.

그래서 보통 전체건수의 1%~2% 이내의 결과를 가져올때만 인덱스가 효율적이라고 합니다.

(제 경험으론 대용량의 경우에 1%도 많아요 ㅜㅜ)

 

인덱스의 구조나 엑세스 방식에 대한 자료를 좀 더 찾아보시면 금방 이해되시리라 생각합니다. ^^

 

 

 

 

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