Adicionar índices secundários às Coleções de séries temporais
Nesta página
Para melhorar o desempenho da query para coleções de séries temporais, adicione um ou mais índices secundários para ter compatibilidade com padrões comuns de query de séries temporais. Especificamente, recomendamos que você crie um ou mais índices compostos nos campos especificados como timeField
e metaField
. Se o valor do campo metaField
for um documento, você poderá criar índices secundários em campos dentro desse documento.
Observação
Nem todos os tipos de índice são suportados. Para obter uma lista de tipos de índice sem suporte, consulte Limitações para índices secundários em coleções de séries temporais.
Por exemplo, este comando cria um índice composto nos campos metadata.sensorId
e timestamp
:
db.weather24h.createIndex( { "metadata.sensorId": 1, "timestamp": 1 } )
Use índices secundários para melhorar o desempenho de classificação
As coleções de séries temporais podem usar índices para melhorar o desempenho de classificação no timeField
e no metaField
.
Por exemplo, a seguinte coleção sensorData
contém medições de sensores meteorológicos:
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, } } ] )
As coleções de séries temporais criam automaticamente um índice interno agrupado. O planejador de query utiliza esse índice para melhorar o desempenho de classificação.
Observação
Se você inserir um documento em uma coleção com um valor timeField
antes 1970-01-01T00:00:00.000Z
ou depois 2038-01-19T03:14:07.000Z
, o MongoDB registrará um aviso e impedirá que algumas otimizações de query usem o índice interno. Criar um índice secundário no timeField
para recuperar o desempenho da query e resolver o aviso de log.
A seguinte operação de classificação no campo timestamp
utiliza o índice agrupado para melhorar o desempenho:
db.sensorData.find().sort( { "timestamp": 1 } )
Para confirmar que a operação de classificação utilizou o índice agrupado, execute a operação novamente com a opção .explain( "executionStats" )
:
db.sensorData.find().sort( { "timestamp": 1 } ).explain( "executionStats" )
O winningPlan.queryPlan.inputStage.stage
é COLLSCAN
e um estágio _internalBoundedSort
está presente no resultado do plano de explicação. O campo interalBoundedSort
indica que o índice clusterizado foi usado. Para obter mais informações sobre como explicar a saída do plano, consulte explicar resultados.
O índice secundário em collection de time-series podem melhorar o desempenho das operações de classificação e aumentar o número de cenários em que os índices podem ser usados.
As operações de classificação em coleções de séries temporais podem utilizar índices secundários no timeField
. Em certas condições, operações de classificação também podem utilizar índices secundários compostos no metaField
e timeField
.
The Aggregation Pipeline Stages $match
and $sort
determine which indexes a Time Series collection can use. A seguinte lista descreve cenários onde um índice pode ser utilizado:
Classificar em
{ <timeField:> ±1 }
utiliza o índice agrupadoClassificar em
{ <timeField>: ±1 }
utiliza um índice secundário em<timeField>
Classificar em
{ <metaField>: ±1, timeField: ±1 }
utiliza um índice secundário em{ <metaField>: ±1, timeField: ±1 }
A classificação em
{ <timeField>: ±1 }
utiliza um índice secundário em{ metaField: ±1, timeField: ±1 }
quando há um predicado de ponto em<metaField>
Criar um índice secundário no campo timestamp
:
db.sensorData.createIndex( { "timestamp": 1 } )
A seguinte operação de classificação no campo timestamp
utiliza o Índice Secundário para melhorar o desempenho:
db.sensorData.aggregate( [ { $match: { "timestamp" : { $gte: ISODate("2022-01-15T00:00:00.000Z") } } }, { $sort: { "timestamp": 1 } } ] )
Para confirmar que a operação de classificação usou o Índice Secundário, execute a operação novamente com a opção .explain( "executionStats" )
:
db.sensorData.explain( "executionStats" ).aggregate( [ { $match: { "timestamp": { $gte: ISODate("2022-01-15T00:00:00.000Z") } } }, { $sort: { "timestamp": 1 } } ] )
Queries do "último ponto" em Coleções de séries temporais
Uma query de "último ponto" obtém a medição mais recente para cada valor de metadados único. Por exemplo, para obter a leitura de temperatura mais recente de todos os sensores. Aprimore o desempenho das mais recentes queries de ponto criando qualquer um dos seguintes índices:
{ "metadata.sensorId": 1, "timestamp": 1 } { "metadata.sensorId": 1, "timestamp": -1 } { "metadata.sensorId": -1, "timestamp": 1 } { "metadata.sensorId": -1, "timestamp": -1 }
Observação
As últimas queries de ponto têm o maior desempenho quando usam a otimização DISTINCT_SCAN. Esta otimização só está disponível quando um índice em timeField
é descendente.
O seguinte comando cria um índice secundário composto no metaField
(ascendente) e timeField
(descendente):
db.sensorData.createIndex( { "metadata.sensorId": 1, "timestamp": -1 } )
O último exemplo de query de ponto seguinte utiliza o índice secundário composto timeField
descendente criado acima:
db.sensorData.aggregate( [ { $sort: { "metadata.sensorId": 1, "timestamp": -1 } }, { $group: { _id: "$metadata.sensorId", ts: { $first: "$timestamp" }, temperatureF: { $first: "$currentConditions.tempF" } } } ] )
Para confirmar que a mais recente query de ponto utilizou o índice secundário, execute a operação novamente utilizando .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" } } } ] )
O winningPlan.queryPlan.inputStage.stage
é DISTINCT_SCAN
, o que indica que o índice foi utilizado. Para obter mais informações sobre a saída do plano de explicação, consulte Explicar resultados.
Especificar Dicas de Índice para Coleções de Séries Temporais
Sugestões de índice fazem com que MongoDB use um índice específico para uma query. Algumas operações em coleções de séries temporais só podem tirar proveito de um índice se esse índice for especificado em uma dica.
Por exemplo, a seguinte query faz com que MongoDB utilize o índice timestamp_1_metadata.sensorId_1
:
db.sensorData.find( { "metadata.sensorId": 5578 } ).hint( "timestamp_1_metadata.sensorId_1" )
Em uma coleção de séries temporais, você pode especificar dicas usando o nome do índice ou o padrão da chave do índice. Para obter os nomes dos índices em uma coleção, utilize o método db.collection.getIndexes()
.
índice secundário de time-series no MongoDB 6.0
A partir do MongoDB 6.0, você pode:
Adicione um índice composto nos campos
timeField
,metaField
ou medição.Use os operadores
$or
,$in
e$geoWithin
com índices parciais em uma coleção de séries temporais.Adicione um índice parcial em
metaField
etimeField
.Adicione um índice secundário a qualquer campo ou subcampo.
Use o
metaField
com índices 2dsphere.
Observação
Se houver coleções de séries temporais e você precisar fazer downgrade da versão de compatibilidade de recursos (FCV), primeiro descartará todos os índices secundários que são incompatíveis com o FCV rebaixado. Consulte setFeatureCompatibilityVersion
.