[MySQL] Adaptive Hash Index

Roy·2024년 1월 19일
0

Real MySQL 8.0

목록 보기
1/8

보통 MySQL에서 사용되는 인덱스라고 하면, B-Tree(Balanced Tree) 인덱스, R-Tree 인덱스 정도만 알고 있었다.
Adaptive Hash Index라는 것을 처음 알게 되었다.
흔히들 인덱스는 B-Tree 특정 값을 빠르게 찾아주는 알고리즘으로 알고 있었는데, 항상 그렇지 않다고 한다.

B-Tree 알고리즘은 루트 노드를 거쳐, 브랜치 노드, 리프 노드까지 찾아야 원하는 레코드가 나오는 꽤 복잡한 구조였다.
이를 수많은 쓰레드로 실행하게 됐을 때, 쿼리 성능은 떨어지게 된다.

Adaptive Hash Index는 B-Tree의 약점을 보완하기 위한 InnoDB의 기능이다.
InnoDB 스토리지 엔진에서 자주 읽히는 데이터의 키값을 이용해, Hash Index를 만들고,
필요할 때마다 Adaptive Hash Index를 이용해 원하는 레코드를 즉시 찾을 수 있다.

즉, B-Tree의 루트/브랜치/리프 노드를 탐색하지 않아도 된다.
Hash Index는 <인덱스 키 값>과 그 값이 저장된 <데이터 페이지 주소>의 쌍으로 관리된다.
<인덱스 키 값>은 다시 <B-Tree 인덱스의 고유번호>와 <B-Tree 인덱스의 실제 키 값>의 조합으로 생성된다.
<데이터 페이지 주소>는 실제 키 값이 저장된 데이터 페이지의 메모리 주소를 가진다. (InnoDB 버퍼 풀에 로딩된 페이지의 주소)

다음과 같은 쿼리가 실행할 때, Adaptive Hash Index의 이점을 확인할 수 있다.

SELECT id FROM arbitrary_table WHERE col IN (?, ?, ?, ?, ...);

모든 공학적 기법이 그렇듯, Adaptive Hash Index가 언제나 좋은 것은 아니다.

성능 향상에 도움이 되는 경우

  • 디스크의 데이터가 InnoDB 버퍼 풀 크기와 비슷한 경우(디스크 읽기가 많지 않은 경우)
  • 동등 조건 검색(동등 비교와 IN 연산자)이 많은 경우
  • 쿼리가 데이터 중에서 일부 데이터에만 집중되는 경우

성능 향상에 무관한 경우

  • 디스크 읽기가 많은 경우
  • 특정 패턴의 쿼리가 많은 경우(JOIN이나 LIKE 패턴 검색)
  • 매우 큰 데이터를 가진 테이블의 레코드를 폭넓게 읽는 경우

Adaptive Hash Index의 메모리 사용량은 다음과 같이 performance_schema를 이용해서 확인할 수 있다.

SELECT EVENT_NAME, CURRENT_NUMBER_OF_BYTES_USED
FROM PERFORMANCE_SCHEMA.MEMORY_SUMMARY_GLOBAL_BY_EVENT_NAME
WHERE EVENT_NAME='memory/innodb/adaptive hash index';

더 자세한 내용은 https://tech.kakao.com/2016/04/07/innodb-adaptive-hash-index/ 여기를 참고하시면 좋을 것 같습니다.

profile
Backend Engineer

0개의 댓글