将二级索引添加到时间序列集合

为了提高时间序列集合的查询性能,添加一个或多个二级索引以支持常见的时间序列查询模式。具体来说,我们建议您在指定为和 的字段上创建一个或多个复合索引。如果该字段的字段值是一个文档,您可以在该文档内的字段上创建二级索引。timeField``metaField``metaField

NOTE

并非所有索引类型都受支持。有关不受支持的索引类型的列表,请参阅时间序列集合上二级索引的限制。

例如,此命令在和 字段上创建复合索引:metadata.sensorId``timestamp

db.weather24h.createIndex( { "metadata.sensorId": 1, "timestamp": 1 } )

TIP

db.collection.createIndex()

使用二级索引提高排序性能img

时间序列集合可以使用索引来提高timeField和上的排序性能metaField

例如,以下sensorData集合包含来自天气传感器的测量值:

db.sensorData.insertMany( [ {
     "metadata": {
         "sensorId": 5578,
         "location": {
             type: "Point",
             coordinates: [-77.40711, 39.03335]
         }
     },
     "timestamp": ISODate("2022-01-15T00:00:00.000Z"),
     "currentConditions": {
         "windDirecton": 127.0,
         "tempF": 71.0,
         "windSpeed": 2.0,
         "cloudCover": null,
         "precip": 0.1,
         "humidity": 94.0,
     }
   },
   {
     "metadata": {
         "sensorId": 5578,
         "location": {
             type: "Point",
             coordinates: [-77.40711, 39.03335]
         }
     },
     "timestamp": ISODate("2022-01-15T00:01:00.000Z"),
     "currentConditions": {
         "windDirecton": 128.0,
         "tempF": 69.8,
         "windSpeed": 2.2,
         "cloudCover": null,
         "precip": 0.1,
         "humidity": 94.3,
     }
   },
   {
     "metadata": {
         "sensorId": 5579,
         "location": {
             type: "Point",
             coordinates: [-80.19773, 25.77481]
         }
     },
     "timestamp": ISODate("2022-01-15T00:01:00.000Z"),
     "currentConditions": {
         "windDirecton": 115.0,
         "tempF": 88.0,
         "windSpeed": 1.0,
         "cloudCover": null,
         "precip": 0.0,
         "humidity": 99.0,
     }
    }
  ]
)

时间序列集合自动创建聚集索引。在某些情况下,查询计划器可能会自动使用聚簇索引来提高排序性能。有关聚簇索引的更多信息,请参阅聚簇索引。

以下对时间戳字段的排序操作使用聚簇索引来提高性能:

db.sensorData.find().sort( { "timestamp": 1 } )

要确认排序操作使用了聚簇索引,请使用以下.explain( "executionStats" )选项再次运行该操作:

db.sensorData.find().sort( { "timestamp": 1 } ).explain( "executionStats" )

winningPlan.queryPlan.inputStage.stageis和阶段COLLSCAN存在 _internalBoundedSort于解释计划输出中。该interalBoundedSort字段表示使用了聚簇索引。有关解释计划输出的更多信息,请参阅解释结果。

时间序列集合的二级索引可以提高排序操作的性能,并增加可以使用索引的场景数量。

时间序列集合的排序操作可以使用timeField. 在某些情况下,排序操作也可以在metaField和上使用复合二级索引timeField

聚合管道阶段$match$sort确定时间序列集合可以使用哪些索引。以下列表描述了可以使用索引的场景:

  • 排序依据{ <timeField:> ±1 }使用聚簇索引
  • 排序依据{ <timeField>: ±1 }使用二级索引 <timeField>
  • 排序依据{ <metaField>: ±1, timeField: ±1 }使用二级索引{ <metaField>: ±1, timeField: ±1 }
  • 排序依据在有点谓词时{ <timeField>: ±1 }使用二级索引 { metaField: ±1, timeField: ±1 }``<metaField>

在字段上创建二级索引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 } }
] )

时间序列集合的“最后一点”查询img

“最后一点”查询获取每个唯一元数据值的最新测量值。例如,您可能希望从所有传感器获取最新的温度读数。通过创建以下任何索引来提高最后一点查询的性能:

{ "metadata.sensorId": 1,  "timestamp": 1 }
{ "metadata.sensorId": 1,  "timestamp": -1 }
{ "metadata.sensorId": -1, "timestamp": 1 }
{ "metadata.sensorId": -1, "timestamp": -1 }

NOTE

最后一点查询在使用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,表示使用了索引。有关解释计划输出的更多信息,请参阅解释结果。

为时间序列集合指定索引提示img

索引提示使 MongoDB 使用特定索引进行查询。如果在提示中指定了索引,则对时间序列集合的某些操作只能利用该索引。

例如,以下查询导致 MongoDB 使用 timestamp_1_metadata.sensorId_1索引:

db.sensorData.find( { "metadata.sensorId": 5578 } ).hint( "timestamp_1_metadata.sensorId_1" )

在时间序列集合上,您可以使用索引名称或索引键模式指定提示。要获取集合中索引的名称,请使用db.collection.getIndexes()方法。

MongoDB 6.0 中的时间序列二级索引img

从 MongoDB 6.0 开始,您可以:

NOTE

如果时间序列集合上有二级索引并且您需要降级功能兼容版本 (FCV),则必须首先删除与降级后的 FCV 不兼容的所有二级索引。看setFeatureCompatibilityVersion

设置时间序列数据的粒度将数据迁移到时间序列集合中

原文链接 -https://www.mongodb.com/docs/manual/core/timeseries/timeseries-secondary-index/

译者:陆文龙

Copyright © 上海锦木信息技术有限公司 all right reserved,powered by Gitbook文件修订时间: 2023-09-01 17:10:26

results matching ""

    No results matching ""