제목은 거창하지만 mongodb 공식 문서의 Optimize Query Performance chapter를 번역한 내용이다.
들어가기 전 mongodb에서 사용되는 단어를 간단히 정리해보자.
Create Indexes to Support Queries
쿼리를 지원하기 위한 index를 만들고, 여러 개의 field를 검색할 경우에는 comfound index를 만든다. index를 스캐닝하는 것이 collection을 스캐닝하는 것보다 빠르기 때문이다. index 구조는 document의 reference보다 작고, index는 reference를 순서대로 저장한다.
블로그 게시물들을 담은 post collection이 있고 글쓴 사람의 이름 field를 sorting하는 쿼리를 자주 날린다면, author_name field에 index를 만들어 쿼리를 최적화할 수 있다.
db.posts.createIndex( { author_name : 1 } )
mongodb는 index를 오름차순, 내림차순으로 읽을 수 있기 때문에 single-key index의 방향은 중요하지 않다. index는 쿼리, update operation, aggregation pipeline의 일부를 지원한다.
Limit the Number of Query Results to Reduce Network Demand
네트워크의 요구 사항을 줄이기 위해 쿼리가 내보내는 결과의 수를 제한할 것. mongodb cursor는 여러 document들의 그룹을 결과로 반환한다. 만약 원하는 결과의 개수를 알고 있다면, limit method를 사용해 네트워크 자원에게 요구하는 양을 줄일 수 있다.
전형적으로 sort operation과 결합할 때 쓰인다. 예를 들어 post collections에서 10개의 결과만 필요하다면, 아래 명령을 할 수 있다.
db.posts.find().sort( { timestamp : -1 } ).limit(10)
Use Projections to Return Only Necessary Data
필요한 데이터만 반환하도록 Projection을 사용할 것. document로부터 field들의 subset만 필요하다면, 필요한 field들만 반환해 더 좋은 퍼포먼스를 낼 수 있다.
예를 들어, post collection에서 timestamp, title, author, 그리고 abstract만 필요하다면 아래 command를 쓸 수 있다.
db.posts.find( {}, { timestamp : 1 , title : 1 , author : 1 , abstract : 1} ).sort( { timestamp : -1 } )
Use $hint to Select a Particular Index
특정 index를 선택하기 위해 $hint를 사용할 것. 대부분의 경우 query optimizer는 특정 operation을 위한 최적의 index를 선택한다. 반면 hint method를 통해 mongodb에게 특정한 index를 쓰라고 강요할 수 있다.
퍼포먼스 테스트에 쓰거나, field를 필수적으로 선택해야 하는 쿼리, 또는 여러개의 인덱스를 포함하는 필드에서 사용하면 좋다.
Use the Increment Operator to Perform Operations Server-Side
서버 사이드 operation을 하기 위해 imcrement operator를 사용할 것. document의 value를 증가시키거나 감소시킬 때, $inc operator를 사용하는 것이 좋다. 해당 operator는 특정document를 선택 -> 클라이언트에서 바꾼 다음 -> 전체 document를 서버에 쓰는 대신에, 서버 사이드에서 field의 value를 증가시켜준다.
그리고 race condition도 피할 수 있다. 하나의 document로 두 개의 application instance들이 쿼리했을 때 나타날 수 있는 상황인데, field를 수동으로 증가시키고 전체 document에 동시에 저장하게 해줄 수 있다.