ESR(동일성, 정렬, 범위) 규칙
여러 필드를 참조하는 인덱스는 복합 인덱스입니다. 복합 인덱스는 쿼리 응답 시간을 크게 향상할 수 있습니다.
인덱스 키는 문서 필드에 해당합니다. 대부분의 경우 ESR(동등성, 정렬, 범위)) 규칙을 적용하여 인덱스 키를 정렬하면 더욱 효율적인 복합 인덱스를 만드는 데 도움이 됩니다.
이 페이지에서는 ESR 규칙을 소개합니다. 쿼리 최적화에 관한 자세한 내용은 explain
및 쿼리 계획을 참조하세요.
팁
MongoDB가 특정 인덱스를 사용하도록 강제하려면 cursor.hint()를 인덱스 테스트 시 사용합니다.
동등성
'동등성'은 단일 값에 대한 정확한 일치를 나타냅니다. 다음의 정확한 일치 쿼리는 model
필드가 Cordoba
와 정확히 일치하는 문서를 찾기 위해 cars
컬렉션을 스캔합니다.
db.cars.find( { model: "Cordoba" } ) db.cars.find( { model: { $eq: "Cordoba" } } )
인덱스 검색은 정확한 일치 항목을 효율적으로 사용하여 쿼리를 완료하기 위해 검사해야 하는 문서 수를 제한합니다. 정확히 일치해야 하는 필드를 인덱스에서 가장 먼저 배치합니다.
인덱스에는 정확히 일치하는 쿼리에 대한 여러 개의 키가 있을 수 있습니다. 동등성 매치를 위한 인덱스 키는 어떤 순서로든 표시될 수 있습니다. 그러나 인덱스와의 동등성 매치를 충족하려면 정확한 매치에 대한 모든 인덱스 키가 다른 인덱스 필드 앞에 와야 합니다. MongoDB의 검색 알고리즘을 사용하면 정확한 매치 필드를 특정 순서로 정렬할 필요가 없습니다.
정확한 일치는 선택적으로 이루어져야 합니다. 스캔되는 인덱스 키 수를 줄이려면 동등성 테스트를 통해 문서 일치 가능성이 90% 이상 제거되는지 확인하세요.
Sort
'정렬'은 결과에 대한 순서를 결정합니다. 동등성 매치가 이루어지면 정렬해야 하는 문서 수가 줄어들기 때문에 정렬은 동등성 매치 후에 실시합니다. 또한 동등성 매치 후 정렬을 수행하면 MongoDB가 비-차단 정렬을 수행할 수 있습니다.
쿼리 필드가 인덱스 키의 하위 집합인 경우 인덱스는 정렬 작업을 지원할 수 있습니다. 인덱스 키의 하위 집합에 대한 정렬 작업은 쿼리에 정렬 키 앞에 오는 모든 접두사 키에 대한 동등성 조건이 포함된 경우에만 지원됩니다. 자세한 내용은 인덱스의 정렬 및 접두사가 없는 하위 집합을 참조하세요.
다음 예시에서는 cars
컬렉션을 쿼리합니다. 출력은 model
을 기준으로 정렬됩니다.
db.cars.find( { manufacturer: "GM" } ).sort( { model: 1 } )
쿼리 성능을 향상하려면 manufacturer
및 model
필드에 인덱스를 생성하세요.
db.cars.createIndex( { manufacturer: 1, model: 1 } )
manufacturer
가 첫 번째 키인 이유는 동등성 매치이기 때문입니다.model
은 쿼리와 동일한 순서(1
)로 인덱싱됩니다.
범위
'범위' 필터는 필드를 스캔합니다. 스캔에는 정확한 일치가 필요하지 않습니다. 이는 범위 필터가 인덱스 키에 느슨하게 바인딩되어 있음을 의미합니다. 쿼리 효율성을 높이려면 범위 경계를 제한하고 동등성 매치 항목을 사용하여 스캔할 문서 수를 줄이세요.
범위 필터는 다음과 유사합니다.
db.cars.find( { price: { $gte: 15000} } ) db.cars.find( { age: { $lt: 10 } } ) db.cars.find( { priorAccidents: { $ne: null } } )
MongoDB는 범위 필터의 결과에 대해 인덱스 정렬을 수행할 수 없습니다. 범위 필터를 정렬 술어 뒤에 배치하여 MongoDB가 비-차단 인덱스 정렬을 사용할 수 있도록 합니다. 차단 정렬에 대한 자세한 내용은 cursor.allowDiskUse()
를 참조하세요.
추가 고려 사항
$regex
는 범위 연산자입니다.$in
을(를) 단독으로 사용하면 일련의 동등성 매치를 수행하는 등호 연산자입니다..sort()
와 함께$in
을 사용하는 경우:$in
에 배열 요소가 200개 미만인 경우 요소는 확장된 다음 인덱스에 지정된 정렬 순서대로 병합됩니다. 이렇게 하면 소규모 배열의 성능이 향상됩니다.$in
ESR의 동등성 조건자와 유사합니다.$in
에 200개 이상의 요소가 있는 경우 요소는 범위 연산자처럼 정렬됩니다. 이 시나리오에서는 소규모 배열에 대한 성능이 향상되지 않습니다. 인덱스의 후속 필드에서 정렬을 제공할 수 없으며$in
은 ESR을 사용하는 범위 조건자와 유사합니다.일반적으로 소규모 배열에
$ins
를 사용하는 경우 인덱스 사양의 앞부분에$ins
를 포함하세요. 일반적으로 대규모 배열을 사용하는 경우 범위 조건자를 포함할 위치에$ins
를 포함하세요.
참고
200개 제한은 변경될 수 있으며 모든 MongoDB 버전에서 동일하게 유지되지 않을 수 있습니다.
예시
다음 쿼리는 가격이 $15,000 이상인 Ford 제조 차량에 대한 cars
컬렉션을 검색합니다. 결과는 모델별로 정렬됩니다.
db.cars.find( { manufacturer: 'Ford', cost: { $gt: 15000 } } ).sort( { model: 1 } )
쿼리에는 ESR 규칙의 모든 요소가 포함되어 있습니다.
manufacturer: 'Ford'
는 동등성 기반 일치입니다.cost: { $gt: 15000 }
는 범위 기반 일치입니다.model
은 정렬에 사용됩니다.
ESR 규칙에 따라 예시 쿼리에 대한 최적의 인덱스는 다음과 같습니다.
{ manufacturer: 1, model: 1, cost: 1 }
추가 논의
여러 MongoDB 컨퍼런스 프레젠테이션에서 ESR 규칙에 대해 심도 있게 논의합니다.