보통 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가 언제나 좋은 것은 아니다.
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/ 여기를 참고하시면 좋을 것 같습니다.