B-Tree 인덱스란?
B-Tree 인덱스는 MySQL에서 가장 널리 사용되는 인덱스 타입이다. B-Tree는 데이터가 정렬된 상태로 저장되어 있다. 그래서 삽입과 삭제 시 정렬이 필연적으로 발생하게 된다. 노드의 자식들의 위치가 정해져 있어서 범위 검색에 유리하다. B-Tree의 구조는 루트노드, 브랜치 노드, 리프 노드로 구성되며, 각 노드는 여러 개의 키를 가질 수 있다.
B-Tree 인덱스는 특히 범위 검색이 자주 필요한 경우에 적합하다. 예를 들어, 날짜 범위 내의 데이터를 검색하거나 특정 값보다 크거나 작은 값을 찾을 때 효과적이다. 또한, B-Tree 인덱스는 기본적으로 정렬된 상태를 유지하기 때문에, ORDER BY 절이나 GROUP BY 절을 포함한 쿼리에서도 이점을 가질 수 있다.
하지만 B-Tree 알고리즘은 루트 노드를 거쳐, 브랜치 노드, 리프 노드까지 찾아야 원하는 레코드가 나오는 꽤 복잡한 구조이다. 만약 이를 수많은 쓰레드로 실행하게 됐을 때, 쿼리 성능은 떨어지게 된다.
Adaptive Hash Index
Adaptive Hash Index는 B-Tree의 약점을 보완하기 위한 InnoDB의 기능이다.
InnoDB 스토리지 엔진에서 자주 읽히는 데이터의 키값을 이용해, Hash Index를 만들고, 필요할 때마다 Adaptive Hash Index를 이용해 원하는 레코드를 즉시 찾을 수 있다.
하지만 모든 값이 해시로 생성되는 것이 아니라 자주 사용되는 데이터 값만 해시 값으로 생성하므로, Adaptive Hash Index에 할당되는 메모리는 전체 Innodb_Buffer_Pool_Szie의 1/64 만큼으로 초기화 된다.
Hash 인덱스란?
Hash 인덱스는 해싱을 사용하여 인덱스를 구성하는 방식이다. Hash 인덱스는 데이터 값을 해시 함수로 변환하여 해시 테이블의 특정 위치에 데이터를 저장한다. 따라서, 정확한 값에 대한 검색(정확한 매칭)에 매우 빠른 성능을 보인다. 하지만, 범위 검색이나 정렬이 필요한 경우에는 적합하지 않다. 왜냐하면, 해시 함수가 데이터의 순서를 유지하지 않기 때문에 특정 범위에 속하는 데이터를 쉽게 찾을 수 없기 때문이다.
Hash 인덱스는 정확한 키 - 값 매칭이 필요한 경우에 적합하다. 예를 들어, 특정 Id나 키 값으로 데이터를 검색할 때 사용한다. MySQL의 InnoDB 스토리지 엔진은 Hash 인덱스를 지원하지 않지만, Memory 스토리지 엔진에선 주로 사용한다.
또한 해시 충돌 발생할 경우 성능 저하가 발생한다는 해시 테이블의 본질적인 문제는 Hash 인덱스에도 동일하게 존재한다. 이로 인해 해시 인덱스를 활용하더라도 탐색에 걸리는 시간이 증가할 수 있다.
B-Tree vs Hash 차이점과 선택 기준
B-Tree와 Hash 인덱스는 그 구조와 사용 목적에서 크게 차이가 난다. B-Tree 인덱스는 범위 검색, 정렬된 데이터 부분 일치를 포함한 다양한 쿼리에서 강점을 보이는 반면, Hash 인덱스는 정확한 일치가 필요한 경우 빠르게 데이터를 찾을 수 있다.
MySQL에서 인덱스 생성 및 관리 방법
MySQL에서 인덱스를 생성하는 방법은 CREATE INDEX 구문을 사용하면 된다. 예를 들어, B-Tree 인덱스를 생성하려면
CREATE INDEX idx_name ON table_name (column_name);
Hash 인덱스를 생성하려면 memory 테이블에서 USING HASH 옵션을 사용해야 한다.
CREATE INDEX idx_name ON table_name (column_name) USING HASH;
인덱스를 관리할 때는 성능을 위해 정기적으로 인덱스를 재구성하거나 필요 없는 인덱스는 삭제하는 것이 좋다.
왜 Hash가 아닌 B-Tree가 사용되는 걸까?
Hash를 사용하면 데이터의 양과 무관하게 데이터의 Hash값만 있으면 매우 빠른 속도로 데이터를 조회할 수 있다. 그런데 왜 이러한 자료구조는 DB에 사용되지 않는 것일까?
실제 서비스를 만들 때는 당연하게도 단일 데이터 조회뿐만 아니라 데이터의 범위를 조회해야 하는 일이 매우 빈번하다.
이러한 측면이 있기 때문에 Hash를 사용하는 자료구조는 적절하지 않게 되는 것이고, B트리 계열의 자료구조가 DB의 인덱스에는 사용되고 있다.
결론
B-Tree와 Hash 인덱스는 MySQL에서 중요한 인덱스 기술이다. 각 인덱스의 특성을 이해하고 적절히 활용하면 데이터베이스 성능을 최적화할 수 있다.