Esta página describe las mejores prácticas para mejorar el rendimiento y el uso de datos para recopilaciones de series temporales.
Mejores prácticas de compresión
Para optimizar la compresión de datos para colecciones de series temporales, realice las siguientes acciones:
Omitir campos que contienen objetos y matrices vacíos de los documentos
Si sus datos contienen objetos, matrices o cadenas vacíos, omita los campos vacíos de sus documentos para optimizar la compresión.
Por ejemplo, considere los siguientes documentos:
{ timestamp: ISODate("2020-01-23T00:00:00.441Z"), coordinates: [1.0, 2.0] }, { timestamp: ISODate("2020-01-23T00:00:10.441Z"), coordinates: [] }, { timestamp: ISODate("2020-01-23T00:00:20.441Z"), coordinates: [3.0, 5.0] }
coordinates Los campos con valores rellenados y los campos coordinates con una matriz vacía generan un cambio de esquema en el compresor. Este cambio hace que el segundo y el tercer documento de la secuencia permanezcan sin comprimir.
Optimice la compresión omitiendo los campos con valores vacíos, como se muestra en los siguientes documentos:
{ timestamp: ISODate("2020-01-23T00:00:00.441Z"), coordinates: [1.0, 2.0] }, { timestamp: ISODate("2020-01-23T00:00:10.441Z") }, { timestamp: ISODate("2020-01-23T00:00:20.441Z"), coordinates: [3.0, 5.0] }
Redondear datos numéricos a unos pocos decimales
Redondee los datos numéricos a la precisión que requiera su aplicación. Redondear los datos numéricos a menos decimales mejora la tasa de compresión.
Mejores prácticas para usar campos incrustados estándar
Si un El modelo de datos integrado satisface las necesidades de su aplicación y utiliza campos anidados. El comportamiento de los campos anidados no difiere entre colecciones regulares y colecciones de series temporales.
Por ejemplo, considere una colección de series de tiempo que contiene documentos meteorológicos similares al siguiente ejemplo:
{ timestamp: ISODate("2024-06-17T10:00:00Z"), stationId: "ALPHA123", atmosphere: { temperature: 21.5, humidity: 68, pressure: 1013.25 }, wind: { speed: 7.2, direction: "NW" }, precipitation: 0.5, visibility: 10 }
MongoDB utiliza la compresión de columnas en cada campo anidado individualmente, lo que proporciona la misma calidad de compresión que si se aplanaran los campos al nivel superior. La compresión resultante es idéntica a la que se obtendría si se aplanaran todos los campos anidados a los campos de nivel superior.
Importante
La compresión de columnas requiere un orden de campos anidados consistente. Sin embargo, si utiliza un controlador para interactuar con sus datos, puede haber consideraciones de ordenación adicionales. Por ejemplo, consulte Tipos BSON para consideraciones de representación ordenada del controlador Go. Consulte la documentación del controlador para obtener más información.
Si su carga de trabajo tiene una cardinalidad alta, aplanar los objetos anidados puede mejorar el rendimiento. Por ejemplo, el siguiente documento contiene los mismos datos que el documento anterior, pero en formato aplanado:
{ timestamp: ISODate("2024-06-17T10:00:00Z"), stationId: "ALPHA123", atmosphere_temperature: 21.5, atmosphere_humidity: 68, atmosphere_pressure: 1013.25 wind_speed: 7.2, wind_direction: "NW" precipitation: 0.5, visibility: 10 }
Nota
Utilice el modelo de datos más adecuado para su aplicación. MongoDB solo recomienda simplificar los documentos si una estructura anidada causa problemas de rendimiento significativos.
Inserta mejores prácticas
Para optimizar el rendimiento de inserción de colecciones de series temporales, realice las siguientes acciones:
Escritura de documentos por lotes
Al insertar varios documentos:
Para evitar viajes de ida y vuelta en la red, utilice una sola declaración en
insertMany()insertOne()lugar de múltiples declaraciones.Si es posible, inserte datos que contengan valores
metaFieldidénticos en los mismos lotes.Establezca el parámetro
orderedenfalse.
Por ejemplo, si tiene dos sensores que corresponden a dos valores metaField, sensor A y sensor B, un lote que contiene múltiples mediciones de un solo sensor incurre en el costo de una inserción, en lugar de una inserción por medición.
La siguiente operación inserta seis documentos, pero solo cuesta dos inserciones (una por cada valor metaField), ya que los documentos se ordenan por sensor. El parámetro ordered se establece en false para mejorar el rendimiento:
db.temperatures.insertMany( [ { metaField: { sensor: "sensorA" }, timestamp: ISODate("2021-05-18T00:00:00.000Z"), temperature: 10 }, { metaField: { sensor: "sensorA" }, timestamp: ISODate("2021-05-19T00:00:00.000Z"), temperature: 12 }, { metaField: { sensor: "sensorA" }, timestamp: ISODate("2021-05-20T00:00:00.000Z"), temperature: 13 }, { metaField: { sensor: "sensorB" }, timestamp: ISODate("2021-05-18T00:00:00.000Z"), temperature: 20 }, { metaField: { sensor: "sensorB" }, timestamp: ISODate("2021-05-19T00:00:00.000Z"), temperature: 25 }, { metadField: { sensor: "sensorB" }, timestamp: ISODate("2021-05-20T00:00:00.000Z"), temperature: 26 } ], { "ordered": false } )
Utilice un orden de campos coherente en los documentos
El uso de un orden de campos coherente en sus documentos mejora el rendimiento de inserción y compresión.
Nota
La compresión requiere un orden coherente de los campos anidados. Para obtener más información sobre la compresión con campos anidados, consulte Prácticas recomendadas para campos anidados.
Por ejemplo, insertar los siguientes documentos, todos ellos con el mismo orden de campos, da como resultado un rendimiento óptimo.
{ _id: ObjectId("6250a0ef02a1877734a9df57"), timestamp: ISODate("2020-01-23T00:00:00.441Z"), name: "sensor1", range: 1 }, { _id: ObjectId("6560a0ef02a1877734a9df66"), timestamp: ISODate("2020-01-23T01:00:00.441Z"), name: "sensor1", range: 5 }
Por el contrario, los siguientes documentos no alcanzan un rendimiento óptimo, porque sus órdenes de campo difieren:
{ range: 1, _id: ObjectId("6250a0ef02a1877734a9df57"), name: "sensor1", timestamp: ISODate("2020-01-23T00:00:00.441Z") }, { _id: ObjectId("6560a0ef02a1877734a9df66"), name: "sensor1", timestamp: ISODate("2020-01-23T01:00:00.441Z"), range: 5 }
Aumentar el número de clientes
Aumentar la cantidad de clientes que escriben datos en sus colecciones puede mejorar el rendimiento.
Mejores prácticas de fragmentación
Para optimizar la fragmentación en su colección de series temporales, realice la siguiente acción:
Utilice metaField como su clave de fragmento
El uso de metaField para fragmentar su colección proporciona cardinalidad suficiente como clave de fragmentación para colecciones de series de tiempo.
Nota
A partir de MongoDB 8.0, el uso de timeField como clave de fragmento en colecciones de series de tiempo está obsoleto.
Mejores prácticas de consulta
Para optimizar las consultas en su colección de series temporales, realice las siguientes acciones:
Establezca un estratégico metaField al crear la colección
Su elección de metaField tiene el mayor impacto en la optimización de las consultas en su aplicación.
Selecciona los campos que casi nunca o nunca cambian como parte de tu metaField.
Si es posible, selecciona identificadores u otros valores estables que sean frecuentes en las expresiones de filtro como parte de tu metaField.
Evita seleccionar campos que no se usen para filtro como parte de tu metaField. En su lugar, utiliza esos campos como mediciones.
Para obtener más información, consulta metaField Considerations.
Establecer la granularidad del depósito adecuada
Al crear una colección de series temporales, MongoDB agrupa los datos entrantes de series temporales en segmentos. Al configurar la granularidad con precisión, se controla la frecuencia con la que se segmentan los datos en función de la tasa de ingesta.
A partir de MongoDB 6.3, puede usar los parámetros de agrupación personalizados bucketMaxSpanSeconds y bucketRoundingSeconds para especificar los límites de los grupos y controlar con mayor precisión cómo se agrupan los datos de series de tiempo.
Puede mejorar el rendimiento configurando granularity o los parámetros de segmentación personalizados para que coincidan lo mejor posible con el intervalo de tiempo entre las mediciones entrantes de la misma fuente de datos. Por ejemplo, si registra datos meteorológicos de miles de sensores, pero solo registra datos de cada sensor una vez cada 5 minutos, puede configurar granularity en "minutes" o los parámetros de segmentación personalizados en 300 (segundos).
En este caso, configurar granularity a hours agrupa hasta un mes de eventos de ingesta de datos en un solo contenedor, lo que resulta en tiempos de recorrido más largos y consultas más lentas. Configurarlo en seconds genera múltiples contenedores por intervalo de sondeo, muchos de los cuales podrían contener un solo documento.
La siguiente tabla muestra el intervalo de tiempo máximo incluido en un grupo de datos cuando se utiliza un valor granularity determinado:
granularity | granularity límite de bucket |
|---|---|
| 1 hora |
| 24 horas |
| 30 días |
Crear índices secundarios
Para mejorar el rendimiento de las consultas, cree uno o más índices secundarios en timeField y metaField para que admitan patrones de consulta comunes. En las versiones 6.3 y posteriores, MongoDB crea automáticamente un índice secundario timeField en metaField y.
Mejores prácticas para índices adicionales
Utilice el índice metaField para filtrar e igualdad.
Utilice timeField y otros campos indexados para consultas de rango.
Las estrategias generales de indexación también se aplican a las colecciones de series temporales. Para más información, consulte Estrategias de Indexación.
Consultar en metaField subcampos
MongoDB reordena el metaField de las colecciones de series temporales, lo que puede provocar que los servidores almacenen los datos en un orden de campos distinto al de las aplicaciones. Si un metaField es un objeto, las consultas en el metaField pueden producir resultados incoherentes, ya que el orden de los metaField puede variar entre servidores y aplicaciones. Para optimizar las consultas en una serie temporal metaField, consulte el metaField en subcampos escalares en lugar de en todo el metaField.
El siguiente ejemplo crea una colección de series temporales:
db.weather.insertMany( [ { metaField: { sensorId: 5578, type: "temperature" }, timestamp: ISODate( "2021-05-18T00:00:00.000Z" ), temp: 12 }, { metaField: { sensorId: 5578, type: "temperature" }, timestamp: ISODate( "2021-05-18T04:00:00.000Z" ), temp: 11 } ] )
La siguiente consulta en los subcampos escalares sensorId y type devuelve el primer documento que coincide con los criterios de consulta:
db.weather.findOne( { "metaField.sensorId": 5578, "metaField.type": "temperature" } )
Ejemplo de salida:
{ _id: ObjectId("6572371964eb5ad43054d572"), metaField: { sensorId: 5578, type: 'temperature' }, timestamp: ISODate( "2021-05-18T00:00:00.000Z" ), temp: 12 }
Utilice $group en lugar de Distinct()
Debido a la estructura de datos única de las colecciones de series temporales, MongoDB no puede indexarlas eficientemente para valores distintos. Evite usar el distinct comando o db.collection.distinct() el método auxiliar en colecciones de series temporales. En su lugar, utilice una agregación para agrupar documentos por valores distintos, como se muestra en el siguiente $group ejemplo:
db.foo.createIndex({"meta.project":1, "meta.type":1}) db.foo.aggregate([{$match: {"meta.project": 10}}, {$group: {_id: "$meta.type"}}])
Esto funciona de la siguiente manera: