AWS document DB의 Index

모지리 개발자·2023년 3월 31일
0

database

목록 보기
2/2

Intro

사내에서 AWS Document DB(v4.x)를 사용하고 있습니다. 최근에 이상한 동작을 발견해서 이 내용을 정리하고자 글을 작성했습니다.

Document DB란

AWS Document DB
공식 문서에 따르면 Amazon DocumentDB는 MongoDB와 호환되는 빠르고 안정적인 종합 관리형 데이터 서비스 입니다. 간단히 말해서 MongoDB와 같은 nosql DB입니다. 위 링크에서 더 자세한 내용은 확인할 수 있습니다

Document DB의 Index 이상동작

이상한 동작은 다음과 같았습니다.

A라는 table이 있고 필드는 위와 같다고 가정하겠습니다.
Index는 총 3개가 있는 상태였습니다.
1. _id
2. b_1_c_1
3. b_1_d_1_f_1

이 상태에서 만약에 아래와 같은 쿼리를 실행한다면 Index를 탈까요?

db.A.find({d : 'something'})

인덱스를 어느정도 공부해봤고 복합인덱스에 대해 알고있다면 위와 같은 쿼리는 Index를 타지 않을 것이라고 알 수 있습니다.

위의 인덱스 예시에서 3번 인덱스에 d 필드가 복합키로 걸려있긴 하지만 b 필드가 없기 때문에 3번 인덱스를 타지 못합니다.

근데 이상하게 Document DB에서 해당 쿼리가 Index를 타는 것이었습니다.

그리고 많은 테이블들 중에 딱 이 한 테이블만 이상하게 동작했습니다.

공식문서 찾아보기

그 동안 제가 공부했던 것이 완전히 잘못됐고 잘못알고있던게 분명하다고 생각했습니다. 그래서 공식문서를 다시 찾아봤습니다.

prefix 조건이 없으면 인덱스를 사용 못한다고 나와있는 공식문서들
몽고 디비 관련 복합키 아티클 : https://www.mongodb.com/docs/manual/core/index-compound/#prefixes
다큐먼트 디비 복합키 관련 아티클 : https://aws.amazon.com/ko/blogs/database/how-to-index-on-amazon-documentdb-with-mongodb-compatibility/

그리고 내부에는 아래와 같이 적혀있습니다.

A compound index can be used on the prefix of the index key (the first, or leading, field of the index), but queries on a non-prefix field generally don't use an index.

위의 내용을 해석해보자면 아래와 같습니다.

복합 인덱스는 인덱스 키의 접두사(인덱스의 첫 번째 또는 선행 필드)에서 사용할 수 있지만 접두사가 아닌 필드에 대한 쿼리는 일반적으로 인덱스를 사용하지 않습니다.

위의 내용에서 보시면 아시겠지만 접두사가 아닌 필드에 대한 쿼리는 인덱스를 사용하지 않는다고 적혀있습니다.

한가지 걸리는 점이 있다면 위의 내용에서 적혀있는 것과 같이 "generally" "일반적으로" 라는 내용이 너무 궁금해서 뭐가 일반적인 상황이라는 건지 찾아보고 싶었지만 아무리 찾아봐도 잘 나오지 않았습니다.

혹시 알고계신 정보가 있다면 한번 알려주시면 감사하겠습니다.

테이블의 특징

문제가 생긴 테이블은 모든 테이블들 중에 데이터가 가장 많은 테이블이었습니다.

추측한 원인

확실한 원인은 아니지만 아래의 링크에서 원인을 추측할 수 있었습니다.
MongoDB Query Plans

위 링크에 들어가보시면 아래와 같은 diagram을 확인 할 수 있습니다.

그리고 인덱스를 찾지 못할 경우 동작 방식에 대해서는 아래와 같이 작성되어있습니다.

중요한 내용은 "Winning plan을 선택한다" 인 듯합니다.

위에서 작성했던 예시로 생각하면
1. b 필드로 조회한다.
2. 인덱스를 발견하지 못했다.
3. winning plan을 설정한다.
4. 인덱스를 타는게 더 낫다고 내부적으로 판단해서 인덱스를 태운다.

내부적으로 어떤 판단을 어떻게 내리는지도 자료를 찾기가 힘드네요ㅜ


추가로 알아낸 내용이 있다면 아래에 더 추가하도록 하겠습니다.

결론

그동안 많은 쿼리를 작성하면서 실제로 explain()을 하지않고 Index를 타겠지, 안타겠지 상상만 하면서 코드를 작성했었는데 앞으로는 실제로 어떤 방식으로 쿼리가 동작하는지 항상 확인해봐야 할 것 같습니다...

profile
항상 부족하다 생각하며 발전하겠습니다.

0개의 댓글