Query performance를 최적화하는 방법✨

yeeun lee·2020년 10월 17일
0

제목은 거창하지만 mongodb 공식 문서의 Optimize Query Performance chapter를 번역한 내용이다.

Optimize query performance

들어가기 전 mongodb에서 사용되는 단어를 간단히 정리해보자.

  • database: 사용할 데이터베이스의 이름. 한 개 이상의 collection을 가진다.
  • collection: 관계형 DB의 table과 유사한 개념이다.
  • document: document들은 collection에 저장된다.
  • cursor: 쿼리 결과에 대한 포인터. 클라이언트는 결과를 검색하기 위해 cursor를 iterate할 수 있다. 기본적으로 Cursor의 timeout은 비활성화되고 10분 뒤이다.

인덱스 만들기

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)

Projection 사용하기

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 } )

$hint 사용하기

Use $hint to Select a Particular Index

특정 index를 선택하기 위해 $hint를 사용할 것. 대부분의 경우 query optimizer는 특정 operation을 위한 최적의 index를 선택한다. 반면 hint method를 통해 mongodb에게 특정한 index를 쓰라고 강요할 수 있다.

퍼포먼스 테스트에 쓰거나, field를 필수적으로 선택해야 하는 쿼리, 또는 여러개의 인덱스를 포함하는 필드에서 사용하면 좋다.

Incremental Operator 사용하기

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에 동시에 저장하게 해줄 수 있다.

profile
이사간 블로그: yenilee.github.io

0개의 댓글