뭐든 즐기면서 ;)

MongoDB indexing / MongoDB 인덱싱 2(복합 인덱스) 본문

DB(데이타베이스)/MongoDB

MongoDB indexing / MongoDB 인덱싱 2(복합 인덱스)

Tada.*+ 2023. 6. 14. 20:07
728x90

인덱스를 username에만 준 상태에서 아래와 같이 쿼리하였을 때(= 인덱스가 앞부분에 놓이지 않을 때), 해당 인덱스는 속도를 향상시키는 데에 큰 도움이 되지 않는다. 

> db.users.find().sort({"age": 1, "username": 1});

위 쿼리의 속도를 향상 시키기 위해서는 복합 인덱스를 사용해야 한다. 복합 인덱스 생성은 아래와 같이 한다.

> db.users.createIndex({"age": 1, "username": 1});

위에서 생성한 인덱스는 아래와 같은 형태로 표현된다.

//[나이, userId] -> 레코드 식별자(record identifier)
[0, "user100020"] -> 8623513776
[0, "user1002"] -> 8599246768
[0, "user100388"] -> 8623560880
[0, "user100414"] -> 8623564208
...
[1, "user100113"] -> 8623525680
[1, "user100280"] > 8623547056
[1, "user100551"] -> 8623581744
[1, "user100626"] -> 8623591344
...
[2, "user100191"] -> 8623535664
[2, "user100195"] -> 8623536176
[2, "user100197"] -> 8623536432
...

레코드 식별자는 DB내부에서 스토리지 엔진에 의해 사용되며 도큐먼트 데이터를 찾는다.

 

몽고DB가 실행하는 쿼리의 종류에 따라 인덱스를 사용하는 방법

동등 쿼리

> db.users.find({"age": 2}).sort({"username": 1})

// collection scan(전체 스캔)을 하지 않고, age가 2인 것부터 탐색한 후 userId 순서대로 정렬한다.
[2, "user100191"] -> 8623535664
[2, "user100195"] -> 8623536176
[2, "user100197"] -> 8623536432

범위 쿼리

> db.users.find({"age": {"$gte": 21, "$lte": 30}})

// 범위 쿼리일 땐 우선 age 21~30 범위에 맞는 index를 조회한다.
// 몽고DB는 index("age")를 사용하여 쿼리를 하면 일반적으로 index순서에 따라 결과를 보여준다. username은 검색 조건에 없음을 유의하자.
[21, "user100295"] -> 8623535664
[21, "user100191"] -> 8623536176
[21, "user100197"] -> 8623536432
...
[29, "user1001"] -> 8623555667
[30, "user1005"] -> 8623516171
[30, "user1002"] -> 8623526434

다중값 쿼리

> db.users.find({"age": {"$gte": 21, "$lte": 30}}).sort({"username": 1})

// age 21~30인 도큐먼트를 찾고, 몽고DB가 원하는 순서대로 정렬해놓은 것을 그대로 결과 반환해주기 전에, 메모리 상에서 username 순서대로 정렬을 해야 한다.
// 이는 위의 쿼리보다 속도가 오래 걸린다는 것을 의미한다.
[21, "user200191"] -> 8623535664
[21, "user200195"] -> 8623536176
[29, "user100197"] -> 8623536432

* 복합 인덱스를 생성할 때에는 정렬 키를 첫 번째에 두면 좋다.

728x90
Comments