정보공간_1

[4기 대구 박병권] 데이터베이스 해시 인덱스 사용법 본문

IT 놀이터/Elite Member Tech & Talk

[4기 대구 박병권] 데이터베이스 해시 인덱스 사용법

알 수 없는 사용자 2013. 11. 28. 03:56

안녕하십니까!

 

대구멤버십 21-2기 박병권입니다.

 

저는 데이터베이스 인덱스 활용 기법에 대해 이야기를 하고자 합니다!

데이터베이스에서 인덱스는 정말 중요한 기법입니다

대용량 데이터베이스를 관리할수록 효율적인 성능을 이끌어 내기 위해 꼭필요한 것이 인덱싱기법입니다.

    

인덱싱이란

인덱스는 MySQL이 데이터를 효율적으로 조회할 수 있도록 돕는 데이터구조입니다. 인덱스는 성능 향상에 있어 필수적입니다. 인덱스는 데이터가 커질수록 중요해집니다. 작고 부하가 적은데이터베이스는 적당한 인덱스가 없어도 대체로 잘 작동하지만 데이터 집합이 커질수록 성능이 급속히 떨어질 가능성이 있습니다.

 

인덱싱 종류

인덱스의 종류는 다양합니다. 서로 다른 용도로 작동하도록 설계되어 있습니다. 인덱스는 서버 계층이 아닌 스토리지 엔진 계층에서 구현되므로 표준화 되어 있지 않습니다. 인덱스는 엔진마다 조금씩 다르게 작동하며 모든 엔진이 모든 타입의 인덱스를 지원하는 건 아닙니다.

 

- B-TREE 인덱스

- 해시 인덱스

- R-TREE 인덱스

- 전문 인덱스

 

다양한 인덱스 종류 중 해시 인덱스에 대해 알아보려고 합니다.

해시 인덱스는 해시 테이블 기반이며, 인덱스를 구성하는 모든 칼럼을 이용하는 경우 유용합니다.

스토리지 엔진은 각행마다 인덱스된 칼럼의 해시코드를 계산하는데, 이 해시 코드는 작은 값을 가집니다. 그리고 키 값이 다른 행이라면 해시 코드 값이 달라지게 됩니다. 스토리지 엔진은 해시 코드를 인덱스에 저장하며, 각 행을 가리키는 포인터는 해시 테이블에 저장됩니다.

 

MySQL에서 해시 인덱스는 Memory 스토리지 엔진에서만 지원합니다. Memory 테이블은 B-TREE 인덱스도 지원하지만 기본 인덱스 유형으로는 명시적 해시 인덱스를 사용합니다.

예를 들어

CREATE TABLE testhash(

first_name VARCHAR(50) NOT NULL,

last_name VARCHAR(50) NOT NULL,

KEY USING HASH(first_name)

)ENGINE=MEMORY;

KEY USING HASH(first_name) : first_name을 해시함수에 넣어 해시값을 구하여 사용합니다.

스토리지 엔진은 MEMORY로 설정

 

테이블에 위와 같은 데이터가 들어있다고 가정합니다.

위 데이터는 실제로는 아래와 같이 데이터가 변환할 것입니다.

예를 들어 해시 값이 위와 같이 변환되어 있다고 가정합니다.

주의 할 점은 슬롯은 정렬되어 있지만 행은 정렬되어 있지 않습니다.

 

mysql> SELECT last_name FROM testhash WHERE first_name='Bred'

 

위 쿼리를 실행하게 되면 Bred의 해시를 계산한 뒤 그 값을 이용해서 인덱스에 든 포인터를 조회합니다. Bred의 해시값 2455에 포인터를 찾아 찾으려던 Bred가 맞는지 확인하게 됩니다.

인덱스 자체는 작은 해시 값만 저장하므로 해시 인덱스는 매우 크기가 작습니다. 해시 값의 길이는 인덱스 하는 칼럼의 형과는 무관합니다. TINYINT 칼럼의 해시 인덱스는 긴 문자열 칼럼의 해시 인덱스와 크기가 같습니다.

이 때문에 해시 인덱스를 사용하면 눈깜짝할 사이에 탐색이 이루어 집니다.

 

속도가 빠른 장점이 있지만 여러 가지 단점도 존재합니다.

- 해시데이터가 정렬되어 있지 않기 때문에 데이터 정렬시 사용하기 어려움

- 충돌이 없다면 빠른 속도로 할 수 있지만 충돌이 생길 경우 포인터를 따라가서 그 값이 찾는 값과 동일한지 확인작업이 필요

- 해시 인덱스를 사용한다면 연산자들을 이용한 동일성 비교만 할 수 있으며 WHERE price>100 과 같은 범위 쿼리를 빨리 처리하지 못함

 

 


참고문헌

1. MySQL 성능 최적화 / 위키북스 / 배론 슈와츠 지음