MongoDB 공부 및 적용 : Index

정재헌·2023년 3월 30일
0

Database

목록 보기
5/6

MongoDB를 이용한 프로젝트를 진행하게 되어, MongoDB에 대한 공부를 함께 진행 중에 있다. 처음에는 좀 더 편하게 이해하기 위하여 MongoDB를 사용한 회사들의 기술 블로그를 바탕으로 공부를 하였으며, 이제는 좀 더 깊은 이해를 위해서 공식 문서를 바탕으로 블로그를 작성해보고자 한다.

첫 번째 MongoDB 블로그에서, MongoDB 기본 설정과 MongoDB의 장점들에 대허 간략하게 알아 보았다. 두 번째에는, MongoDB에서 이야기하는 좋은 데이터 모델링과 MongoDB 내 relation type인 embedding과 referencing에 대해서 알아보았다. 세 번째에는, Node.js application에서의 MongoDB CRUD operation과 transaction에 대해 알아보고자 한다.

오늘은 MongoDB 내 읽기 및 업데이트에 대한 쿼리 성능 향상을 위해 사용하는 Index에 대해 알아보고자 한다.

Index

  • Special data structures
  • Store small portion of the data
  • Ordered and easy to search efficiently
  • Point to the document identity

MongoDB 공식 문서에서 정의한, index에 대한 내용이다. MongoDB 공식 문서에 따르면, Index를 통해 데이터를 더 빠르게 검색, 액세스 및 업데이트를 할 수 있다고 한다.

왜 사용? 쿼리 성능 향상을 위해!

앞에서도 이야기한 바와 같이, Index는 쿼리 성능 향상을 위해 사용한다. Index를 통해 누릴 수 있는 향상 효과는 아래와 같다.

  • 쿼리 속도 향상
  • disk I/O 감소
  • 필요 자원 효율적 사용
  • 동등 일치, 범위 기반 조작 같은 쿼리 지원 + 결과 반환

Index가 어떻게 작용하길래?

만약 Index가 없다면, MongoDB는 collection의 모든 document를 읽어야 하며, 메모리에 결과를 정렬해야 한다. 하지만 Index를 사용한다면, 쿼리를 기반으로 Index를 통해 식별된 document만 fetch하기 때문에 결과를 더욱 빠르게 return 할 수 있다.

유의할 사항

하지만, Index를 사용하는 것이 만능인 것은 아니다. Index를 사용한다는 것은 write-performance cost를 발생시키는 것이기 때문이다. 그 이유는 아래와 같다.

  • collection에 새 document를 삽입하거나, Index field를 갱신하는 경우 Index 구조의 데이터도 함께 갱신해야 한다.
  • collection에 Index가 너무 많은 경우, 쓰기 성능이 저하될 수 있다.
  • 그렇기 때문에, 불필요하거나 중복되는 Index는 삭제해야 한다.

Most Index type in MongoDB

single field / compound field / multikey index

Creating a single field index in MongoDB

createIndex()

  • 고유 제한 조건을 사용하여 field값에 고유값 적용 가능
  • getIndexes() : collection 내 index 식별
  • explain() : 쿼리가 인덱스를 사용하고 있는지 판별

Creating a Multikey index(Index on an array field) in MongoDB

어떻게 배열 field의 index와 작동하는지에 대해 알 수 있다.

Working with compound indexes in MongoDB

<진행 순서>
1. Equality (쿼리 처리 속도 감소, 더 적은 수의 문서 검색)
2. Sort (결과 순서 정렬)
3. Range

코드 적용 예시 : pagination

const getAllPost = async(pageNumber: number) => {

    const pageSize = 10
    const skip = (pageNumber -1) * pageSize
    const sortField = 'post_date'
    const sortOrder = -1

    const imageDataBypage = await Post.find()
                                .limit(pageSize)
                                .skip(skip)
                                .sort({[sortField]: sortOrder})

    return imageDataBypage
}
// index 개념을 적용하면, 아래와 같은 방식으로 code를 수정할 수 있을 것 같다.

// Page 1
users = db.users.find().sort({'_id': 1}).limit(pageSize);

// Remember the last _id value from this page
last_id = users[users.length-1]._id;

// Page 2
users = db.users.find({'_id': {'$gt': last_id}}).sort({'_id': 1}).limit(pageSize);
profile
백엔드 개발자

0개의 댓글