MongoDB에서 인덱스 방향이 중요한 이유는 무엇입니까?


114

문서 를 인용하려면 :

인덱스를 만들 때 키와 관련된 숫자는 인덱스의 방향을 지정하므로 항상 1 (오름차순) 또는 -1 (내림차순)이어야합니다. 방향은 단일 키 인덱스 또는 임의 액세스 검색에 중요하지 않지만 복합 인덱스에 대해 정렬 또는 범위 쿼리를 수행하는 경우 중요합니다.

그러나 복합 지수에서 지수의 방향이 중요한 이유를 알 수 없습니다. 누군가가 추가 설명 (또는 예)을 제공 할 수 있습니까?

답변:


112

MongoDB는 어떤 방식 으로든 복합 키를 연결하고이를 BTree의 키로 사용합니다.

단일 항목을 찾을 때 -트리의 노드 순서는 관련이 없습니다.

노드 범위를 반환하는 경우 -서로 가까운 요소는 트리의 동일한 분기 아래에 있습니다. 노드가 범위에 가까울수록 더 빨리 검색 할 수 있습니다.

단일 필드 인덱스 사용 -순서는 중요하지 않습니다. 오름차순으로 서로 가깝다면 내림차순으로도 가깝습니다.

복합 키가있을 때 -순서가 중요하기 시작합니다.

예를 들어 키가 A 오름차순 B 오름차순 인 경우 색인은 다음과 같습니다.

행 AB
1 1 1
2 2 6
3 2 7 
4 34
5 3 5
6 3 6
7 5 1

A 오름차순 B 내림차순에 대한 쿼리는 행을 반환하기 위해 순서에 상관없이 인덱스를 건너 뛰어야하며 속도가 느려집니다. 예를 들어 Row를 반환합니다.1, 3, 2, 6, 5, 4, 7

인덱스와 동일한 순서의 범위 쿼리는 단순히 올바른 순서로 순차적으로 행을 반환합니다.

BTree에서 레코드를 찾는 데 O (Log (n)) 시간이 걸립니다. 순서대로 레코드 범위를 찾는 것은 OLog (n) + k입니다. 여기서 k는 반환 할 레코드 수입니다.

레코드가 잘못된 경우 비용은 OLog (n) * k만큼 높을 수 있습니다.


1
결과 행은 아마도 1, 3, 2, 6, 5, 4, 7?
johndodo 2011

여전히 느려질 이유가 없습니다. 알고리즘 만 달라야합니다 (A의 각 값 그룹에 대해 그룹의 끝으로 이동하여 역순으로 처리해야 함) .MongoDB 인덱스는 메모리에 있으므로 속도에 눈에 띄는 영향을주지 않아야합니다. 또한 RDBMS는 인덱스가있는 방향에 대해 전혀 알지 못하며 상황이 매우 유사합니다.
johndodo 2011

8
성능 저하가 발생하는 이유는 단순화 된 예제처럼 메모리의 순차 목록이 아니기 때문입니다. 실제로 가중치가있는 나무입니다. 순서를 벗어나면 나무를 다시 횡단해야합니다. RDMS는 확실히 인덱스 순서를 가지고 있습니다.
Jared Kells 2012

1
순서대로 BTree에서 노드를 가져 오는 것은 다 떨어질 때까지 각 잎을 따라 이동 한 다음 한 수준 위로 올라가 다음 가지로 내려가는 것만 큼 간단합니다. O (n) 고장 나서 훨씬 더 많은 CPU 집약적입니다.
Jared Kells

추가 설명에 감사드립니다. MySQL 색인 에 대한 문서를 확인 했습니다. 실제로 색인 방향을 지정할 수 있지만 설정은 무시됩니다.
johndodo 2012

45

찾고 있는 간단한 대답두 개 이상의 필드에서 정렬 할 때만 방향이 중요 하다는 것 입니다.

정렬하는 경우 {a : 1, b : -1}:

지수는 {a : 1, b : 1}보다 느리게 인덱스{a : 1, b : -1}


1
@MarkPieszak 왜냐하면 전체 정렬은 인덱스를 쓸모 없게 만드는 메모리에서 수행되어야하기 때문입니다.
Sammaye

@Sammaye 나는 그것이 전체 종류 인지 확실하지 않지만 그것이 올바른 생각이라고 생각합니다 . 실제로 작동하는 방식을 알기 위해 구현을 살펴 봐야하지만 결과를 a 단독 으로 정렬 한 다음 추가 b 정렬을 메모리에서 수행해야한다고 생각합니다.
Zaid Masud 2015

1
흠, 마지막으로 코드를 확인했을 때 정렬 방식 때문에 부분 정렬을 떨어 뜨 렸지만 meh, 아마도 변경
되었을 것입니다

에서 정렬하는 {a: -1, b: -1}경우 {a: -1, b: -1}색인이 있어야 하거나 {a: 1, b: 1}충분할 것 입니다.
Hussain

@Hussain 귀하의 예에서 {a: 1, b: 1}인덱스는 인덱스를 완전히 반전하는 것이 좋으므로 충분해야합니다. 예를 들어 인덱스에 {a: 1}에 종류에 사용할 수 있습니다{a: -1}
자이드 마수드

12

왜 인덱스

두 가지 핵심 사항을 이해하십시오.

  1. 인덱스가없는 것보다 낫지 만 올바른 인덱스가 어느 쪽보다 훨씬 낫습니다.
  2. MongoDB는 쿼리 당 하나의 인덱스 만 사용하므로 사용하려는 올바른 필드 순서로 복합 인덱스를 만듭니다.

인덱스는 무료가 아닙니다. 메모리를 차지하고 삽입, 업데이트 및 삭제를 수행 할 때 성능 저하를 부과합니다. 일반적으로 성능 저하는 무시할 수 있지만 (특히 읽기 성능 향상에 비해) 그렇다고 인덱스 생성에 대해 현명 할 수 없다는 의미는 아닙니다.

인덱스 방법

함께 인덱싱해야하는 필드 그룹을 식별하는 것은 실행중인 쿼리를 이해하는 것입니다. 색인을 만드는 데 사용되는 필드의 순서는 매우 중요합니다. 좋은 소식은 주문이 잘못되면 인덱스가 전혀 사용되지 않으므로 Explain으로 쉽게 찾을 수 있다는 것입니다.

왜 정렬

쿼리에 정렬이 필요할 수 있습니다. 그러나 정렬은 비용이 많이 드는 작업이 될 수 있으므로 정렬하는 필드를 쿼리하는 필드처럼 처리하는 것이 중요합니다. 따라서 인덱스가 있으면 더 빠를 것입니다. 하지만 한 가지 중요한 차이점이 있습니다. 정렬하는 필드는 인덱스의 마지막 필드 여야합니다. 이 규칙에 대한 유일한 예외는 필드가 쿼리의 일부인 경우 마지막이어야하는 규칙이 적용되지 않는 것입니다.

정렬 방법

인덱스의 모든 키 또는 하위 집합에 대해 정렬을 지정할 수 있습니다. 그러나 정렬 키는 색인에 나타나는 순서대로 나열되어야합니다. 예를 들어, 인덱스 키 패턴 {a : 1, b : 1}은 {a : 1, b : 1}에서 정렬을 지원할 수 있지만 {b : 1, a : 1}에서는 지원하지 않습니다.

정렬은 인덱스 키 패턴으로 모든 키에 대해 동일한 정렬 방향 (예 : 오름차순 / 내림차순)을 지정하거나 인덱스 키 패턴으로 모든 키에 대해 역 정렬 방향을 지정해야합니다. 예를 들어 인덱스 키 패턴 {a : 1, b : 1}은 {a : 1, b : 1} 및 {a : -1, b : -1}에 대한 정렬을 지원할 수 있지만 {a : -1에 대해서는 지원하지 않습니다. , b : 1}.

다음 색인이 있다고 가정합니다.

{ a: 1 }
{ a: 1, b: 1 }
{ a: 1, b: 1, c: 1 }

Example                                                    Index Used
db.data.find().sort( { a: 1 } )                            { a: 1 }
db.data.find().sort( { a: -1 } )                           { a: 1 }
db.data.find().sort( { a: 1, b: 1 } )                      { a: 1, b: 1 }
db.data.find().sort( { a: -1, b: -1 } )                    { a: 1, b: 1 }
db.data.find().sort( { a: 1, b: 1, c: 1 } )                { a: 1, b: 1, c: 1 }
db.data.find( { a: { $gt: 4 } } ).sort( { a: 1, b: 1 } )   { a: 1, b: 1 }

나는 그 예입니다 이해하지만 인덱스가있는 경우 { a: 1, b: 1, c: 1 }어떻게 당신이 정말로 인덱스가 필요 { a: 1}하고 { a: 1, b: 1}또는 인덱스 { a: 1, b: 1, c: 1 }커버 모든 경우를? 쿼리는 항상 같은 종류를 사용하지 않는 경우 : 쿼리에 하나 더 종류 -1
루카스 Liesis

1
속성 'a'에서만 작동하는 쿼리가 많은 경우 데이터베이스 엔진에 대해 'a'속성이있는 인덱스로 검색하는 것이 'a', 'b', 'c'3 개의 속성이있는 인덱스로 검색하는 것보다 빠릅니다. 인덱스 크기가 증가하고 개수도 증가하기 때문입니다. 전의. 책에 20 개의 장이있는 경우. 따라서 3 장으로 이동 한 다음 특정 페이지로 이동하는 것이 더 빠릅니다. @LukasLiesis
Somnath Muluk
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.