클러스터드 인덱스가 있는 테이블의 경우 데이터는 클러스터드 인덱스의 키로 정렬이됩니다.

이 키로 데이터를 찾을 경우 "Clustered Index Seek"가 발생하게 됩니다.

클러스터드 인덱스가 없는 테이블의 경우 데이터는 추가된 순서대로 쌓이게 됩니다. 그래서 힙이라고 하죠.


이때 넌클러스터드 인덱스를 만들게 되면 넌클러스터드 인덱스의 리프레벨에는 데이타의 위치를 가르키는 RID가 기록됩니다. 넌클러스터드 인덱스로 데이터를 찾을 경우에는 그래서 "RID Lookup"이 발생하게 됩니다. 


근데 클러스터드 인덱스가 있는 테이블에 넌클러스터드 인덱스를 만들면 이 인덱스의 리프레벨에는 RID가 아닌 클러스터드 인덱스의 키가 기록됩니다. 그래서 이 넌클러스터드 인덱스로 데이터를 찾을 경우에는 넌클러스터드 인덱스의 리프레벨에서 클러스터드 인덱스의 키를 확인한 후 이 키를 이용해서 데이터를 찾는 "Key Lookup"이 발생합니다.


"Index Scan"이란 이런겁니다. 

주소록 테이블에 전화번호로 인덱스를 만들었습니다.

근데 찾고 싶은 데이터는 전화번호의 4번째가 7이고 다섯번째와 여섯번째의 차가 3인 그런 데이타입니다. -_-;;

우리가 전화번호부를 이용해서 이런 데이터를 찾으려고 해도... 결국 전화번호부 책을 몽땅 뒤질수밖에 없죠.

SQL SERVER도 마찬가지입니다. 인덱스를 이용해서 저런 데이타를 찾을 수가 없습니다.

그래서 결국 테이블을 몽땅 스캔합니다. 이것이 "Clustered Index Scan" 또는 "Table Scan" 라고 합니다.

근데 찾으려는 데이타가 인덱스의 키에 포함되어 있을 경우 테이블을 몽땅 뒤지는것보다 인덱스를 뒤지는게 더 빠릅니다.

이유는 인덱스 페이지가 더 작을것이기 때문이죠. 이때 발생하는것이 "Index Scan"이라고 합니다.


책을 예로 설명해보면

보통 기술서적들 보면 맨 뒤에 키워드를 인덱스로 만들어놨습니다.

SQL 관련 서적을 예로 들면 "클러스터드 인덱스"에 대해 설명해놓은 페이지를 찾으려면

"ㅋ"섹션에서 "클러스터드 인덱스" 키워드를 찾은 후 517페이지 (<- 이게 RID) 에 있다는 걸 확인한 후 517페이지를 펼치게 됩니다.

이런게 "Index Seek"


근데 키워드 중에 중간에 "덱"이 들어간 페이지를 찾고 싶으면??

인덱스 a~z ㄱ~ㅎ까지 몽땅 확인해야죠? 중간에 "덱"이런거 들어간 키워드가 있나...

이런 동작이 "Index Scan"입니다.

"Index Seek"동작이나 "Index Scan"동작은 어쨋든 인덱스 페이지에서 인덱스 키를 찾는 동작입니다.

이 동작후에는 데이터 페이지로 이동하기 위해 "RID Lookup"이나 "Key Lookup"을 하게 되죠.

클러스터드 인덱스가 있을때는 Key Lookup 넌클러스터드만 있다면 RID Lookup을 하게 됩니다.



근데 만약에 원하는 데이타가 인덱스 키 안에 모두 포함되어 있다면

말하자면 전화번호부 테이블에서 "전화번호, 이름"으로 인덱스가 만들어져 있는데


select 전화번호, 이름 

  from 전화번호부

where 전화번호 = '010-9999-8888' 


이런 쿼리를 날린다면

전화번호와 이름이 모두 인덱스 페이지에 있기 때문에 더 이상 데이터 페이지로 이동하지 않아도 모든 데이터를 확인 할 수 있습니다. 그러면 Lookup 동작 자체를 안하게 됩니다. 인덱스 이외에 같은 행에 있는 데이터를 가져올 필요가 없기 때문이죠. 이런걸 "커버드 인덱스"라고 합니다.


따로 룩업을 안하고 인덱스 페이지에서 모든 데이터를 가져가는것이 마치 클러스터드 인덱스의 동작과 비슷합니다.

그래서 성능이 클러스트드 인덱스에 필적한다고 하죠.

사실 커버드 인덱스란 인덱스의 종류가 따로 있는 것이 아니라 어떤 쿼리가 인덱스 컬럼 내에서만 select 할때

그때 사용된 인덱스가 쿼리를 커버하는 것이죠.

요약

클러스터 인덱스는 테이터에 바로 접근이 가능하다. 리프노드가 데이터 페이지에 있기 때문이다. 하지만 넌클러스터 인덱스는 데이터를 가져오기위해서는 데이터 페이지까지 찾아서 데이터를 가져와야하는데, 이때 RID를 참조해서, 데이터를 LOOK UP해오는 과정을 RID LOOKUP이라한다.

RID

행식별자로서 넌 클러스터 인덱스의 데이터 페이지 번호, 슬롯번호, 파일번호를 16진수 값으로 변환한 값을 말한다.


LOOKUP

인덱스의 리프레벨에 없는 컬럼을 읽어야 한다면, 실제 데이터가 저장된 위치를 찾아가서 읽어오는 작업을 말한다.


RID LOOKUP

RID(데이터페이지변호, 슬롯번호, 파일번호)를 가지고 HEAP에 저장된 실제 데이터를 찾아오는 것.


KEY LOOKUP

클러스터 인덱스가 잡혀있는 테이블에서 넌클러스터인덱스를 만들경우 RID에는 클러스터인덱스의 KEY가 저장된다. 이 KEY를 이용해서 실제 데이터를 찾아오는 과정

특징

RID LOOKUP은 HEAP TABLE에서만 일어난다. 

HEAP TABLE이란 클러스터 인덱스가 없는 테이블을 말한다.

테이블에 클러스터 인덱스가 있으면 그 테이블은 RID LOOKUP이 일어날 수가 없다. KEY LOOKUP이 발생한다.

RID LOOKUP은 항상 NL JOIN과 함께 사용된다.


RID LOOKUP을 발생시키기위한조건

1. 클러스터 인덱스의 부재

2. 넌클러스터 인덱스가 유니크 하지않으면 테이블 스캔이 일어난다.





출처 : http://www.sqler.com/612541 댓글

그림출처 : https://blogs.msdn.microsoft.com/craigfr/2006/06/30/bookmark-lookup/

'SQL > SQL 튜닝' 카테고리의 다른 글

클러스터링 팩터  (0) 2017.10.26
옵티마이저 이해하기 - 2  (0) 2017.10.26
클러스터인덱스와 넌클러스터인덱스  (0) 2017.10.24
Nested Loop, Sort Merge, Hash JOIN  (0) 2017.10.23
옵티마이저 이해하기 - 1  (0) 2017.10.23

+ Recent posts