mongodb 성능 개선 - index 설정

소은비·2021년 12월 1일
0

1. 개요

어느날 서비스를 운영하면서 특정 비디오에 '즐겨찾기'를 표시하는 기능에 문제가 생긴 것을 파악하게 되었습니다. 이 문제는 mongodb의 collection에서 많은 document들이 있는 탓에 search 속도가 매우 느려진 것이 원인인 것으로 파악하였고, 이 문제를 해결한 과정을 적어보려고 합니다.

2. 문제파악

백엔드 쪽에서 문제를 파악하던 중, 개발버전(dev)에서는 잘 작동하고 실제 프로덕트 환경(production)에서만 발생하는 문제라는 것을 발견하였습니다.
dev와 production의 가장 큰 차이점은 db에서 document의 수 였습니다. dev는 팀원들만 사용하는 테스트용인 반면, production은 많은 사용자들이 이용하게 되기 때문입니다.

확인해보니 video들의 정보가 담긴 videos collection에서 즐겨찾기를 누른 영상에 대한 document를 찾아 '즐겨찾기'에 대한 필드값을 true로 바꿔주는 로직 내에서, 해당 영상을 서치하는데 굉장히 오랜 시간이 걸리는 것을 확인하였습니다.

3. 해결방법

mongodb의 성능을 개선하는 여러 방법을 찾아보았고, 여러 방법 중 search하는 key를 db의 index로 설정하는 방법을 시도하였습니다.

아래와 같은 쿼리를 robo3T에서 입력하였습니다.

1) 인덱스 설정

즐겨찾기 api 호출 시, 넘겨받은 video id로 videos collection에서 해당 document를 찾게되므로 video id에 index를 아래와 같이 설정하였습니다.
video id를 나타내는 필드명은 "id"이므로 아래와 같이 createIndex({"id":1})로 해당 필드에 인덱스를 설정할 수 있습니다.

db.getCollection('videos').createIndex({"id": 1})

잘 생성되었다면 output으로 나오는 dodcument는 아래와 같습니다.

2) 인덱스 확인

인덱스 설정 후, 해당 db에 대한 인덱스를 확인하는 방법은 아래와 같습니다.

db.getCollection('videos').getIndexes()

아래와 같이 mongodb에서 자동을 생성되는 Key값인 'id'와 방금 우리가 생성한 'id'가 생긴 것을 확인할 수 있습니다!
새로 생긴 index의 name은 "id_1"이며, 이 이름은 인덱스 제거 시 사용됩니다.
index name은 기본으로 field명 끝에 '
'가 붙은 이름으로 생성됩니다.

3) (혹시 잘못된경우) 인덱스 제거

혹시나 인덱스를 잘못 설정하였거나 제거하고 싶은 경우, 아래와 같은 쿼리를 통해 인덱스를 제거할 수 있습니다.
dropIndex에 제거하고 싶은 index name을 입력하면 됩니다.

db.getCollection('videos').dropIndex("id_1")

4. 결과

postman을 이용하여 문제가 발생하였던 api의 응답속도를 테스트 한 결과, 응답속도가 7.76초에서 0.319초로 20배 이상 개선되었음을 확인하였습니다!

마치며

db에서 index를 설정하는 간단한 방법을 적용함으로써 어마어마하게 성능이 개선됨을 확인하였습니다!
search하는 효율을 위해 db에서 key가 되는 필드값에 index를 잘 활용하면 좋을 것 같습니다.

다만 db에 너무 많은 index를 설정하는 경우 오히려 성능이 저하될 수 있으니 주의해야 합니다.
(보통 하나의 collection에 대해 하나의 index만 설정해주는 것이 권장된다고 합니다!)

다음에는 더 재미있는 글로 찾아뵙겠습니다😆

Reference

https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/

profile
개발자!

0개의 댓글