-
MongoDB - index (1)mongoDB 2022. 4. 17. 16:08
Index는 왜 필요할까? Index는 mongoDB에서 효율적인 쿼리 실행을 도와준다. 만약 index가 없다면 쿼리에 맞는 data를 찾기 위해서 collection의 모든 document를 scan해야 한다. MongoDB에서는 기본적으로 _id field에 대해 index가 존재한다.
Index는 collection의 data set의 작은 부분을 특정 형태의 data structure로 저장한다. 특정한 field나 field의 집합의 값을 값에 따라 순서대로 저장한다.
Single Index
Score 기준으로 indexing 위의 예시를 보면 score 기준으로 indexing을 하고 score: { "$lt": 30 } 이라는 query를 실행했다. 만약 index가 없었다면 collection의 모든 data의 score 값을 확인 해야만 했는데 index가 있기 때문에 score가 30인 지점까지만 확인하면 된다.
Compound Index
MongoDB는 Compound Index,즉 multiple fields index를 지원한다. 여기서 field list의 순서는 매우 중요하다. 만약 index를 생성할 때 {userid:1, score: -1} 으로 생성했다면 우선 userid를 기준으로 오름차순 정렬을 한 뒤에 score를 기준으로 내림차순 정렬을 한 것이기 때문이다.
여기서 생길 수 있는 문제에 대해 알아보자
- {score:-1, userid:1}과 {userid:1, score:-1}은 완전 다른 index 라고 볼 수 있다. 만약 {userid:1, score: -1}으로 index를 생성했다면 query({score: {"$lt":30}})은 score 자체가 userid를 먼저 indexing 한 뒤 indexing 하기 때문에 score라는 단일 field query로는 성능 향상 효과를 볼 수 없다.
- {userid:1, score: -1}로 index를 create 했을 때, {userid:-1, score:1}은 완전 reverse이기 때문에 동일하게 적용된다. 하지만 {userid:-1, score: -1}, {userid:1, score:1}은 index의 성능 향상을 받을 수 없다.
Compound indexing
Multikey Index
MongoDB는 multikey index를 제공한다. Multikey index란 array에 저장된 content에 대해 index를 걸 수 있는 기능이다.
하나의 create index에서 Multikey index는 하나만 사용되어야 한다.
Multikey index 위의 그림에서 find({"addr.zip":{$elemMatch: {$gt: 10000, $lt: 100000}}}) 와 같이 날리면 collection에서 addr.zip의 값이 하나라도 10000보다 크고 100000보다 작다면 그 document를 찾는다.
추가 사항
Unique index 설정하기
Index 생성 시 createIndex(...,{unique: true}) 옵션을 주면 index에 맞는 값을 unique하게 설정할 수 있다.
예를 들어서 게임에서 계정의 name이 중복이 가능하고 하나의 계정에서 동일한 name을 2개 이상 생성할 수 없다고 가정한다면 createIndex({name:1, account:1},{unique: true}) 과 같이 index를 생성하면 name, account field값이 같은 document를 unique하게 설정할 수 있다.
Index 확인하기
Index가 잘 적용됐는지 확인하기 위해서는 query에 explain을 붙여서 확인해보면 된다. 간단히 확인하는 방법의 예를 들면
db.collectionName.find({"addr.zip":{$elemMatch: {$gt: 10000, $lt: 100000}}}).explain() 과 같이 뒤에 .explain()을 붙여서 mongosh에서 확인하면 되는데 이 때, queryPlanner.winningPlan의 indexName을 통해서 내가 설정한 index가 제대로 의도대로 동작했는지 확인할 수 있고, multikey의 경우에는 indexBounds를 통해서 내가 elemMatch를 통해 날린 명령어가 제대로 동작했는지 확인할 수 있다. 만약, rejectedPlans에 있거나 index가 먹지 않고 "stage":"COLLSCAN"으로 나온다면 무엇인가 잘못 된 것을 확인할 수 있다. Explain에서는 추후 자세히 다루도록 하겠다.
'mongoDB' 카테고리의 다른 글
MongoDB Version up에서 발생한 추가 문제사항 (0) 2022.06.06 MongoDB - index (2) (0) 2022.05.29 MongoDB - Data modeling (2) (0) 2022.04.16 MongoDB - Data modeling (1) (0) 2022.04.14 MongoDB - Read Concern (0) 2022.04.04