복합 인덱스 정렬 순서
인덱스는 오름차순(1
) 또는 내림차순(-1
)으로 필드에 대한 참조를 저장합니다. 복합 인덱스 의 경우 정렬 순서에 따라 인덱스가 정렬 작업을 지원할 수 있는지 여부가 결정됩니다.
복합 인덱스는 인덱스의 정렬 순서 또는 인덱스의 역순 정렬과 일치하는 정렬 작업을 지원합니다.
사용 사례
모바일 게임에는 다음 정보를 표시하는 가 있습니다:
최고 게임 점수
각 점수를 달성한 사용자
각 점수를 획득한 날짜
애플리케이션은 먼저 score
기준으로 내림차순으로 리더보드를 정렬합니다. 그런 다음 각 score
와 연관된 username
이 오름차순(알파벳순)으로 정렬됩니다.
인덱스의 정렬 순서가 쿼리의 정렬 순서와 일치하는 경우 복합 인덱스를 사용하면 리더보드의 성능이 향상될 수 있습니다.
예제
다음과 같은 문서가 포함된 leaderboard
컬렉션을 생각해 보세요.
db.leaderboard.insertMany( [ { "score": 50, "username": "Alex Martin", "date": ISODate("2022-03-01T00:00:00Z") }, { "score": 55, "username": "Laura Garcia", "date": ISODate("2022-03-02T00:00:00Z") }, { "score": 60, "username": "Alex Martin", "date": ISODate("2022-03-03T00:00:00Z") }, { "score": 60, "username": "Riya Patel", "date": ISODate("2022-03-04T00:00:00Z") }, { "score": 50, "username": "Laura Garcia", "date": ISODate("2022-03-05T00:00:00Z") } ] )
이 쿼리는 리더보드 결과를 반환합니다:
db.leaderboard.find().sort( { score: -1, username: 1 } )
출력:
[ { _id: ObjectId("632235700646eaee87a56a74"), score: 60, username: 'Alex Martin', date: ISODate("2022-03-03T00:00:00.000Z") }, { _id: ObjectId("632235700646eaee87a56a75"), score: 60, username: 'Riya Patel', date: ISODate("2022-03-04T00:00:00.000Z") }, { _id: ObjectId("632235700646eaee87a56a73"), score: 55, username: 'Laura Garcia', date: ISODate("2022-03-02T00:00:00.000Z") }, { _id: ObjectId("632235700646eaee87a56a72"), score: 50, username: 'Alex Martin', date: ISODate("2022-03-01T00:00:00.000Z") }, { _id: ObjectId("632235700646eaee87a56a76"), score: 50, username: 'Laura Garcia', date: ISODate("2022-03-05T00:00:00.000Z") } ]
결과는 먼저 점수를 기준으로 내림차순으로 정렬한 다음 사용자 이름을 기준으로 오름차순 (알파벳 순) 으로 정렬됩니다.
리더보드의 보조 지표
다음 인덱스는 인덱스의 정렬 순서가 쿼리에 사용된 정렬 순서와 일치하므로 리더보드 결과의 성능을 개선합니다.
db.leaderboard.createIndex( { score: -1, username: 1 } )
이 복합 인덱스는 다음을 저장합니다:
score
값을 내림차순으로 정렬합니다.username
값을 오름차순(알파벳순)으로 정렬합니다.
결과 반전
MongoDB는 어느 방향으로든 복합 인덱스를 탐색할 수 있습니다. 애플리케이션에서 사용자가 리더보드를 역순으로 볼 수 있도록 허용하는 경우 인덱스는 해당 쿼리도 지원합니다.
다음 쿼리는 순위표를 역순으로 반환하며, 결과는 먼저 오름차순 score
값으로 정렬된 다음 내림차순 username
값((알파벳순 역순)으로 정렬됩니다.
db.leaderboard.find().sort( { score: 1, username: -1 } )
출력:
[ { _id: ObjectId("632235700646eaee87a56a76"), score: 50, username: 'Laura Garcia', date: ISODate("2022-03-05T00:00:00.000Z") }, { _id: ObjectId("632235700646eaee87a56a72"), score: 50, username: 'Alex Martin', date: ISODate("2022-03-01T00:00:00.000Z") }, { _id: ObjectId("632235700646eaee87a56a73"), score: 55, username: 'Laura Garcia', date: ISODate("2022-03-02T00:00:00.000Z") }, { _id: ObjectId("632235700646eaee87a56a75"), score: 60, username: 'Riya Patel', date: ISODate("2022-03-04T00:00:00.000Z") }, { _id: ObjectId("632235700646eaee87a56a74"), score: 60, username: 'Alex Martin', date: ISODate("2022-03-03T00:00:00.000Z") } ]
{ score: -1, username: 1 }
인덱스는 이 쿼리를 지원합니다.
지원되지 않는 쿼리
복합 인덱스는 정렬 순서가 인덱스와 일치하지 않거나 인덱스의 반대인 쿼리를 지원할 수 없습니다. 따라서 { score:
-1, username: 1 }
인덱스는 다음 쿼리와 같이 score
값을 오름차순으로 정렬한 다음 username
값을 오름차순으로 정렬하는 것을 지원할 수 없습니다.
db.leaderboard.find().sort( { score: 1, username: 1 } )
또한 정렬 작업에서 인덱스를 사용하려면 정렬에 지정된 필드가 인덱스에 나타나는 순서와 동일한 순서로 나타나야 합니다. 따라서 위의 인덱스는 이 쿼리를 지원할 수 없습니다:
db.leaderboard.find().sort( { username: 1, score: -1, } )
자세히 알아보기
정렬 순서 및 인덱스에 대한 자세한 내용은 인덱스를 사용하여 쿼리 결과 정렬하는 방법을 참조하세요.
쿼리 결과 정렬에 대한 자세한 내용은
sort()
을 참조하세요.