rastalion.dev
MONGODB

MongoDB Index#.3 Hash Index

teinam 2021-03-25updated 09-20 1 MIN

이전 포스팅

MongoDB Index#.2 B-Tree Index

MongoDB의 Hash Index

해시 인덱스는 필드 값의 해시를 저장하는 인덱스입니다. 주어진 키 값을 해싱하여 목표 레코드의 위치를 계산하는 방식이므로, 등가 조건 검색에는 효율적이지만 범위 검색이나 정렬에는 사용할 수 없습니다.

MongoDB에서 해시 인덱스는 주로 해시 샤딩을 위해 사용합니다. 해시 샤딩은 샤드 키 값의 해시를 기준으로 데이터를 샤드 전체에 균등하게 분산시키는 방식으로, ObjectId나 타임스탬프처럼 단조 증가하는 필드를 샤드 키로 사용할 때 특히 유용합니다. 범위 기반 샤딩에서는 단조 증가 키가 단일 청크에 몰려 쓰기가 한 샤드에 집중되지만, 해시 샤딩은 이를 방지합니다.

다만 해시 샤딩을 사용하면 등가 조건 쿼리는 단일 샤드로 라우팅되지만, 범위 쿼리는 모든 샤드로 브로드캐스트됩니다.

내부 구조

MongoDB의 해시 인덱스는 내부적으로 B-Tree 구조에 해시된 값을 저장하는 방식으로 구현됩니다. 해시 인덱스를 생성하면 필드 값의 해시를 64비트 정수로 변환하여 B-Tree 인덱스의 키로 사용합니다. 애플리케이션에서는 해시 인덱스처럼 동작하고 해시 인덱스의 제약을 따르지만, 물리적으로는 B-Tree를 사용합니다.

해시 함수는 자동으로 적용되므로 애플리케이션에서 해시를 직접 계산할 필요는 없습니다. 특정 키의 해시 값을 확인하려면 convertShardKeyToHashed() 메서드를 사용할 수 있습니다.

해시 인덱스 생성

단일 필드 해시 인덱스는 다음과 같이 생성합니다.

db.collection.createIndex({ field: "hashed" })

MongoDB 4.4부터는 복합 해시 인덱스도 지원합니다. 복합 인덱스에서는 정확히 하나의 필드만 "hashed"로 지정할 수 있으며, 나머지 필드는 일반 정렬 순서(1 또는 -1)를 사용합니다.

db.collection.createIndex({
  field1: 1,
  field2: "hashed",
  field3: -1
})

복합 해시 인덱스는 최대 32개 필드를 포함할 수 있으며, 해시 필드의 위치는 제한이 없습니다.

제약 사항

해시 인덱스에는 다음 제약이 있습니다.

  • 범위 쿼리 불가: $gt, $lt 같은 범위 조건은 해시 인덱스를 사용할 수 없습니다.
  • 커버드 쿼리 불가: 해시 인덱스는 커버드 쿼리를 지원하지 않습니다.
  • 배열 필드 불가: 배열이 포함된 필드에는 해시 인덱스를 생성할 수 없으며, 멀티키 인덱스가 될 수 없습니다.
  • unique 제약 불가: 해시 인덱스는 unique 옵션을 지원하지 않습니다. 유일성이 필요하면 별도의 일반 인덱스를 생성해야 합니다.
  • 부동소수점 제한: 해시 함수는 부동소수점 값을 64비트 정수로 절단합니다. 예를 들어 2.2, 2.3, 2.9는 모두 같은 해시 값을 가져 충돌이 발생합니다. 2^53보다 큰 부동소수점 값은 지원되지 않습니다.
  • 서브 도큐먼트: 서브 도큐먼트에 해시 인덱스를 만들면 전체 도큐먼트가 하나의 값으로 처리되므로, 필드 순서가 바뀌면 다른 해시가 생성됩니다.

다음 포스트

MongoDB Index #.4 Multi key Index

참고 자료

Advertisement