[MySQL] 실제 디스크에서 데이터를 읽어오는 시점 1 3 1,039

by 내몸매GROUPBY [MySQL] [2019.05.09 15:50:54]


B-TREE 인덱스를 공부하면서 궁금한점이 생겼습니다.

책을 읽다가 아래 내용을 알게되었습니다.

#WHERE절에 인덱스 컬럼이 조건으로 사용되었다면 리프 노드 탐색 후 디스크로부터 데이터를 읽어온다.

 

QUESTION

1. WHERE절이 사용되지 않았거나 WHERE절에 인덱스 컬럼이 사용되지 않았을 경우 디스크로부터 데이터를 읽어오는 시점은 언제일까요? 즉 인덱스가 걸린 컬럼이 있을 때와 없을 때 데이터를 읽어오는 시점이 달라질까요?

-> FROM절

-> WHERE절

2. WHERE절에 인덱스 컬럼 + 인덱스가 걸리지 않은 컬럼이 사용되었다면 디스크로부터 데이터를 읽어오는 시점은 언제일까요?

첫번째 가정 -> 리프 노드 탐색 -> 조건에 일치하는 데이터를 디스크로부터 읽어옴 -> 읽어온 데이터들중 인덱스가 걸리지 않은 컬럼의 조건과 일치하는 레코드만 선별

(인덱스 컬럼과 일치하는 데이터를 먼저 선별한 후 선별된 데이터 중에서 인덱스가 걸리지 않은 컬럼의 조건과 일치하는지 여부 확인)

두번째 가정 -> 리프 노드 탐색 -> 조건에 일치하는 데이터 발견 -> 레코드 주소를 통해 해당 레코드로 이동 후 인덱스가 걸리지 않은 컬럼의 조건과 일치하는지 확인 -> 일치할 경우 디스크로부터 읽어옴

(인덱스 컬럼의 조건과 일치하는지 확인하면서 같이 인덱스가 걸리지않은 컬럼의 조건도 확인함)

 

3.혹시 리프 노드에 있는 레코드 주소를 통해 해당 레코드를 이동한다는거 자체가 레코드를 디스크로부터 읽어온다는 의미일까요??

by 르매 [2019.05.09 17:55:36]

MySQL InnoDB 기준으로..

- 인덱스의 리프 노드에 데이터의 주소.. 즉 Row ID를 가지고 있지 않습니다.

- "클러스터드 인덱스의 리프 노드 = 데이터" 입니다.

- 넌클러스터드 인덱스의 리프 노드에는 클러스터드 인덱스의 키값이 있습니다.

- 모든 프라이머리 키는 클러스터드 인덱스입니다.

- 프라이머리 키가 없는 테이블에는 보이지 않는 가상의 정수 식별자가 행마다 붙고, 이 가상의 컬럼에 클러스터드 인덱스가 생성됩니다.

위 사실을 이해하셨다고 가정하고 설명드리죠.

1. where 절이 없거나, 있어도 적절한 인덱스가 없다면 프라이머리 키 (클러스터드 키)의 리프노드를 전체 스캔합니다.

프라이머리 키의 리프 노드가 데이터 자체이기 때문에 이 과정에서 테이블의 모든 값을 읽은 것이고, 별도로 데이터를 찾는 과정이 없습니다.

따라서 이것을 테이블 스캔으로 불러도 무방합니다.

2. 인덱스된 컬럼.. 이것이 클러스터드 인덱스라면.. 조건을 만족하는 인덱스 값의 리프 노드에 접근하고, 인덱스 되지 않은 컬럼 조건을 만족하는지 여부를 별도의 io 없이 확인 합니다.

왜?  리프 노드에 모든 컬럼의 값이 있으니까요.

하지만, 넌클러스터드 인덱스라면 리프 노드에서 클러스터드 인덱스의 키 값을 가져와서.. 다시 클러스터드 인덱스의 리프 노드를 접근하고 거기서 나머지 컬럼 조건을 확인합니다. 이런 과정을 key lookup 이라고 합니다.

3. MySQL InnoDB는 행 주소를 사용하는 방식이 없기 때문에 질문의 절반은 오류입니다. 다만.. 메모리의 버퍼 풀을 먼저 찾고.. 없으면 디스크에서 읽어 버퍼 풀에 올린 후 클라이언트에게 반환합니다.


by 타락천사 [2019.05.10 07:43:08]

좋은 정보 감사드립니다. ㅇ.ㅇ


by 양디비 [2019.05.13 09:34:34]

mysql innodb 엔진에 대해 이해하는 데 도움이 많이 되었습니다. 감사합니다!

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