문서 메뉴

문서 홈애플리케이션 개발MongoDB 매뉴얼

Time Series 컬렉션에 보조 인덱스 추가하기

이 페이지의 내용

  • 세컨더리 인덱스를 사용하여 정렬 성능 향상
  • Time Series 컬렉션의 마지막 점 쿼리
  • Time Series 컬렉션에 대한 인덱스 힌트 지정
  • MongoDB 6.0 이상의 Time Series 보조 인덱스

Time Series 컬렉션에 대한 쿼리 성능을 개선하려면 하나 이상의 보조 인덱스를 추가하여 일반적인 Time Series 쿼리 패턴을 지원합니다. MongoDB 6.3부터는 새 컬렉션에 대해 metaFieldtimeField 필드에 복합 인덱스를 자동으로 생성합니다.

참고

모든 인덱스 유형이 지원되는 것은 아닙니다. 지원되지 않는 인덱스 유형 목록은 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 필드의 보조 인덱스을 사용할 수 있습니다. 특정 조건에서 정렬 작업은 metaFieldtimeField 필드에 복합 보조 인덱스를 사용할 수도 있습니다.

aggregation pipeline 단계 $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 컬렉션의 경우 마지막 점 쿼리는 각 고유 메타데이터 값에 대한 최신 측정값을 가져옵니다. 예를 들어 모든 센서에서 최신 온도 측정값을 가져오고 싶을 수 있습니다. 다음 인덱스 중 하나를 생성하여 마지막 점 쿼리의 성능을 개선합니다.

{ "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.stageDISTINCT_SCAN이며, 이는 인덱스가 사용되었음을 나타냅니다. 설명 계획 출력에 대한 자세한 내용은 설명 결과를 참조하세요.

인덱스 힌트는 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() 메서드를 사용합니다.

버전 6.3에 추가.

MongoDB 6.3부터는 Time Series 컬렉션에 대한 부분 TTL 인덱스를 생성할 수 있습니다. metaField에 대해서만 필터링할 수 있습니다.

컬렉션에서 expireAfterSeconds 옵션을 사용하여 문서를 만료하지 않는 경우, 부분 TTL 인덱스를 생성하면 일치하는 문서에 대해서만 만료 시간이 설정됩니다. 컬렉션이 모든 문서에 대해 expireAfterSeconds를 사용하는 경우 부분 TTL 인덱스를 사용하면 일치하는 문서를 더 빨리 만료할 수 있습니다.

버전 6.0에 추가.

MongoDB 6.0부터 다음을 수행할 수 있습니다.

  • timeField, metaField 또는 측정 필드에 복합 인덱스를 추가합니다.

  • Time Series 컬렉션에 부분 인덱스가 있는 $or, $in$geoWithin 연산자를 사용합니다.

  • metaField에 부분 필터 표현식을 추가합니다.

  • 모든 필드 또는 하위 필드에 보조 인덱스를 추가합니다.

  • 2dsphere 인덱스와 함께 metaField를 사용합니다.

    예제

    db.sensorData.createIndex({ "metadata.location": "2dsphere" })
  • 측정값에 2dsphere 인덱스를 생성합니다.

    예제

    db.sensorData.createIndex({ "currentConditions.tempF": "2dsphere" })

참고

Time Series 컬렉션 에 세컨더리 인덱스 가 있고 기능 호환성 버전(fCV)을 다운그레이드해야 하는 경우, 먼저 다운그레이드된 fCV와 호환되지 않는 세컨더리 인덱스를 모두 삭제해야 합니다. 를 setFeatureCompatibilityVersion 참조하세요.

← 시계열 데이터의 세분성 설정