Esta página describe las mejores prácticas para mejorar el rendimiento y el uso de datos en colecciones de series de tiempo.
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 tus datos contienen objetos, arreglos o cadenas vacías, omite los campos vacíos de tus 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.
Optimiza 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] }
Redondea los datos numéricos a unos pocos decimales
Redondea los datos numéricos a la precisión que requiere tu aplicación. Redondear los datos numéricos a menos decimales mejora la relación de compresión.
Mejores prácticas para usar campos incrustados estándar
If an modelo de datos incrustado para satisfacer las necesidades de tu aplicación, usa campos anidados. El comportamiento de los campos anidados no difiere entre las colecciones regulares y las colecciones de series temporales.
Por ejemplo, considera una colección de series de tiempo que contenga 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 compresión por columnas en cada campo anidado de forma individual, lo que ofrece la misma calidad de compresión que al aplanar los campos al nivel superior. La compresión resultante es idéntica a la compresión que resultaría de aplanar todos los campos anidados a 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 BSON types para consideraciones sobre la representación ordenada del controlador de Go. Consulta la documentación del controlador para obtener más información.
Si su carga de trabajo tiene una alta cardinalidad, aplanar objetos anidados puede mejorar el rendimiento. Por ejemplo, el siguiente documento contiene los mismos datos que el documento anterior, pero en un formato simplificado:
{ 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
Use un modelo de datos que sea más natural para tu aplicación. MongoDB solo recomienda aplanar 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:
Guardar documentos agrupar
Al insertar varios documentos:
Para evitar viajes de ida y vuelta a la red, utiliza una única
insertMany()instrucción en lugar de variasinsertOne()instrucciones.Si es posible, inserte datos que contengan valores idénticos de
metaFielden 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 sólo incurre en el costo de dos inserciones (una por cada valor de metaField), porque los documentos están ordenados 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 } )
Usa orden de campo coherente en los documentos
Usar un orden de campos coherente en tus 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 los cuales tienen 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.
Particionado: mejores prácticas
Para optimizar la fragmentación en su colección de series temporales, realice la siguiente acción:
Utilice la metaField como su clave de partición
Utilizar el metaField para particionar tu colección proporciona una cardinalidad suficiente como clave de partición para colecciones de series de tiempo.
Nota
A partir de MongoDB 8.0, el uso de timeField como una clave de partición en colecciones de series de tiempo está obsoleto.
Query mejores prácticas
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
La elección de metaField tiene el mayor impacto en la optimización de las consultas en tu 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 apropiada de los cubos
Cuando se crea una colección de series de tiempo, MongoDB agrupa los datos de series de tiempo entrantes en buckets. Al establecer correctamente la granularidad, tienes control sobre la frecuencia con la que los datos se agrupan en función de la tasa de ingesta de tus datos.
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.
Puedes mejorar el rendimiento configurando los parámetros de agrupamiento granularity o 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 se están registrando datos meteorológicos de miles de sensores, pero solo se registran datos de cada sensor una vez cada 5 minutos, se puede configurar granularity a "minutes" o establecer los parámetros de agrupación personalizada a 300 (segundos).
En este caso, configurar el campo granularity en hours agrupa hasta un mes de eventos de data ingest en un solo bucket, lo que resulta en tiempos de recorrido más largos y consultas más lentas. Establecerlo en seconds conduce a múltiples buckets por intervalo de sondeo, muchos de los cuales podrían contener solo un único documento.
La siguiente tabla muestra el intervalo de tiempo máximo incluido en un bucket de datos cuando se usa un determinado valor granularity:
granularity | granularity límite de bucket |
|---|---|
| 1 hora |
| 24 horas |
| 30 días |
Cree í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 en timeField metaField y.
Prácticas recomendadas adicionales sobre el índice
Use el índice metaField para el filtro y la igualdad.
Utilice timeField y otros campos indexados para consultas de rango.
Las estrategias generales de indexación también aplican a las colecciones de series temporales. Para más información, consulta Estrategias de indexación.
Query el metaField sobre subcampos
MongoDB reorganiza el metaField de las colecciones de series temporales, lo que puede hacer que los servidores almacenen los datos en un orden de campo diferente al de las aplicaciones. Si un metaField es un objeto, las consultas en el metaField pueden producir resultados inconsistentes debido a que el orden metaField puede variar entre servidores y aplicaciones. Para optimizar las queries en una metaField de serie de tiempo, query el metaField en subcampos escalares en lugar de query todo el metaField.
El siguiente ejemplo crea una colección de series de tiempo:
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 }
Utiliza $group en vez de Distinct()
Debido a la estructura única de datos de las colecciones de series temporales, MongoDB no puede indexarlas eficientemente para valores distintos. Evite utilizar el comando distinct o el método asistente db.collection.distinct() en colecciones de series temporales. En su lugar, use una agregación $group para agrupar documentos por valores distintos, como se muestra en el siguiente 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:
Creando un índice compuesto en
meta.projectymeta.typey admite la agregación.La etapa
$matchfiltra los documentos en los quemeta.project = 10.La etapa
$grouputilizameta.typecomo la clave de grupo para generar un documento por cada valor único.