Time Series 컬렉션에 보조 인덱스 추가하기
이 페이지의 내용
Time Series 컬렉션에 대한 쿼리 성능을 개선하려면 하나 이상의 보조 인덱스를 추가하여 일반적인 Time Series 쿼리 패턴을 지원합니다. MongoDB 6.3부터 MongoDB는 새 컬렉션에 대해 metaField
및 timeField
필드에 자동으로 복합 인덱스를 생성합니다.
참고
모든 인덱스 유형이 지원되는 것은 아닙니다. 지원되지 않는 인덱스 유형 목록은 Time Series 컬렉션의 세컨더리 인덱스에 대한 제한 사항을 참조하세요.
세컨더리 인덱스를 추가로 생성할 수도 있습니다. 구성이 포함된 날씨 데이터 컬렉션을 가정해 보겠습니다.
db.createCollection( "weather", { timeseries: { timeField: "timestamp", metaField: "metadata" }})
각 날씨 데이터 문서에서 metadata
필드 값은 기상 센서 ID 및 유형에 대한 필드가 포함된 하위 문서입니다.
{ "timestamp": ISODate("2021-05-18T00:00:00.000Z"), "metadata": { "sensorId": 5578, "type": "temperature" }, "temp": 12 }
컬렉션의 기본 복합 인덱스는 전체 metadata
하위 문서를 인덱싱하므로 인덱스는 $eq
쿼리에만 사용됩니다. 특정 metadata
필드를 인덱싱하면 다른 쿼리 유형에 대한 쿼리 성능이 향상됩니다.
예를 들어, 이 $in
쿼리는 metadata.type
에 대한 보조 인덱스의 이점을 활용합니다.
{ metadata.type:{ $in: ["temperature", "pressure"] }}
세컨더리 인덱스를 사용하여 정렬 성능 향상
Time Series 컬렉션에 대한 정렬 작업은 timeField
필드의 보조 인덱스을 사용할 수 있습니다. 특정 조건에서 정렬 작업은 metaField
및 timeField
필드에 복합 보조 인덱스를 사용할 수도 있습니다.
집계 파이프라인 단계 $match
및 $sort
는 Time Series 컬렉션에서 사용할 수 있는 인덱스를 결정합니다. 인덱스는 다음 시나리오에서 사용할 수 있습니다.
{ <timeField>: ±1 }
정렬은<timeField>
의 세컨더리 인덱스를 사용합니다.{ <metaField>: ±1, timeField: ±1 }
정렬은{ <metaField>: ±1, timeField: ±1 }
의 기본 복합 인덱스를 사용합니다.<metaField>
에 점 조건자가 있는 경우{ <timeField>: ±1 }
에 대한 정렬은{ metaField: ±1, timeField: ±1 }
에 보조 인덱스를 사용합니다.
예를 들어 다음 sensorData
collection에는 날씨 센서의 측정값이 포함되어 있습니다.
db.sensorData.insertMany( [ { "metadata": { "sensorId": 5578, "type": "omni", "location": { type: "Point", coordinates: [-77.40711, 39.03335] } }, "timestamp": ISODate("2022-01-15T00:00:00.000Z"), "currentConditions": { "windDirection": 127.0, "tempF": 71.0, "windSpeed": 2.0, "cloudCover": null, "precip": 0.1, "humidity": 94.0, } }, { "metadata": { "sensorId": 5578, "type": "omni", "location": { type: "Point", coordinates: [-77.40711, 39.03335] } }, "timestamp": ISODate("2022-01-15T00:01:00.000Z"), "currentConditions": { "windDirection": 128.0, "tempF": 69.8, "windSpeed": 2.2, "cloudCover": null, "precip": 0.1, "humidity": 94.3, } }, { "metadata": { "sensorId": 5579, "type": "omni", "location": { type: "Point", coordinates: [-80.19773, 25.77481] } }, "timestamp": ISODate("2022-01-15T00:01:00.000Z"), "currentConditions": { "windDirection": 115.0, "tempF": 88.0, "windSpeed": 1.0, "cloudCover": null, "precip": 0.0, "humidity": 99.0, } } ] )
timestamp
필드에 보조 단일 필드 인덱스를 생성합니다.
db.sensorData.createIndex( { "timestamp": 1 } )
timestamp
필드에 대한 다음 정렬 작업은 보조 인덱스을 사용하여 성능을 향상시킵니다.
db.sensorData.aggregate( [ { $match: { "timestamp" : { $gte: ISODate("2022-01-15T00:00:00.000Z") } } }, { $sort: { "timestamp": 1 } } ] )
정렬 작업에서 세컨더리 인덱스을 사용했는지 확인하려면 .explain( "executionStats" )
옵션을 사용하여 작업을 다시 실행합니다.
db.sensorData.explain( "executionStats" ).aggregate( [ { $match: { "timestamp": { $gte: ISODate("2022-01-15T00:00:00.000Z") } } }, { $sort: { "timestamp": 1 } } ] )
Time Series 컬렉션의 마지막 점 쿼리
Time Series 데이터에서 마지막 점 쿼리는 주어진 필드에 대한 최신 타임스탬프가 있는 데이터 요소를 반환합니다. Time Series 컬렉션의 경우 마지막 점 쿼리는 각 고유 메타데이터 값에 대한 최신 측정값을 가져옵니다. 예를 들어 모든 센서에서 최신 온도 측정값을 가져오고 싶을 수 있습니다. 다음 인덱스 중 하나를 생성하여 마지막 점 쿼리의 성능을 개선합니다.
{ "metadata.sensorId": 1, "timestamp": 1 } { "metadata.sensorId": 1, "timestamp": -1 } { "metadata.sensorId": -1, "timestamp": 1 } { "metadata.sensorId": -1, "timestamp": -1 }
참고
마지막 점 쿼리는 DISTINCT_SCAN 최적화를 사용할 때 가장 성능이 좋습니다. 이 최적화는 timeField
의 인덱스가 내림차순인 경우에만 사용할 수 있습니다.
다음 명령은 metaField
(오름차순) 및 timeField
(내림차순)에 복합 보조 인덱스를 생성합니다.
db.sensorData.createIndex( { "metadata.sensorId": 1, "timestamp": -1 } )
다음 마지막 점 쿼리 예시에서는 위에서 생성된 내림차순 timeField
복합 보조 인덱스를 사용합니다.
db.sensorData.aggregate( [ { $sort: { "metadata.sensorId": 1, "timestamp": -1 } }, { $group: { _id: "$metadata.sensorId", ts: { $first: "$timestamp" }, temperatureF: { $first: "$currentConditions.tempF" } } } ] )
마지막 점 쿼리가 보조 인덱스를 사용했는지 확인하려면 .explain( "executionStats" )
을 사용하여 작업을 다시 실행합니다.
db.getCollection( 'sensorData' ).explain( "executionStats" ).aggregate( [ { $sort: { "metadata.sensorId": 1, "timestamp": -1 } }, { $group: { _id: "$metadata.sensorId", ts: { $first: "$timestamp" }, temperatureF: { $first: "$currentConditions.tempF" } } } ] )
winningPlan.queryPlan.inputStage.stage
는 DISTINCT_SCAN
이며, 이는 인덱스가 사용되었음을 나타냅니다. 설명 계획 출력에 대한 자세한 내용은 설명 결과를 참조하세요.
Time Series 컬렉션에 대한 인덱스 힌트 지정
인덱스 힌트는 MongoDB가 쿼리에 특정 인덱스를 사용하도록 합니다. Time Series 컬렉션에 대한 일부 작업은 인덱스가 힌트에 지정된 경우에만 인덱스를 활용할 수 있습니다.
예를 들어 다음 쿼리는 MongoDB가 timestamp_1_metadata.sensorId_1
인덱스를 사용하도록 합니다.
db.sensorData.find( { "metadata.sensorId": 5578 } ).hint( "timestamp_1_metadata.sensorId_1" )
Time Series 컬렉션에서는 인덱스 이름 또는 인덱스 키 패턴을 사용하여 힌트를 지정할 수 있습니다. 컬렉션에서 인덱스 이름을 가져오려면 db.collection.getIndexes()
메서드를 사용합니다.
2dsphere 인덱스 만들기
버전 6.0부터 timeField
, metaField
또는 측정 필드에 2dsphere 인덱스를 생성할 수 있습니다.
예를 들어, 다음 작업은 location
필드에 2dsphere 인덱스를 생성합니다.
예시
db.sensorData.createIndex({ "metadata.location": "2dsphere" })
또한 다음 작업은 측정 필드에 대한 2dsphere 인덱스를 생성합니다.
예시
db.sensorData.createIndex({ "currentConditions.tempF": "2dsphere" })
참고
Time Series 컬렉션에 세컨더리 인덱스가 있고 기능 호환성 버전(FCV)을 다운그레이드해야 하는 경우, 먼저 다운그레이드된 FCV와 호환되지 않는 보조 인덱스를 모두 삭제해야 합니다. 자세한 내용은 setFeatureCompatibilityVersion
을 참조하세요.