es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

MongoDB muy lento al eliminar muchos y remover

En mi base de datos de MongoDB con 2 réplicas tengo una colección con más de 100 millones de documentos, el tamaño de la colección es de más de 400 GB y el tamaño de los índices es de 150 GB. Tengo que reducir el tamaño de la colección eliminando los registros más antiguos utilizando el campo modifiedOn para el cual tengo un índice de TTL. El índice de TTL eliminará las entradas anteriores a un mes, pero tengo que actuar ahora. He intentado eliminar los registros más antiguos utilizando:

db.myCollection.deleteMany({modifiedOn : {"$lt" : new Date(2021, 12, 20}})

y

db.myCollection.remove({modifiedOn : {"$lt" : new Date(2021, 12, 20}})

Estaba intentando aumentar el día y luego ejecutar la consulta para reducir la carga, pero lleva al menos 10 horas completar estas consultas. Sé que eliminar la colección es la opción más rápida, pero quiero conservar los datos más recientes.

¿Por qué exactamente tarda tanto tiempo en ejecutar estas consultas incluso con un índice para modifiedOn? ¿Es el índice demasiado grande y actualizarlo lleva tanto tiempo? ¿Cuáles son las mejores opciones para eliminar los registros más antiguos?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Explicación

    La razón por la cual las consultas para eliminar los registros más antiguos tardan tanto en ejecutarse, a pesar de tener un índice para modifiedOn, es porque MongoDB necesita escanear toda la colección para encontrar los documentos coincidentes. Esto se debe a que la consulta no es lo suficientemente selectiva y no utiliza ningún otro índice.

    Además, la eliminación de documentos en MongoDB puede ser una operación lenta debido a la forma en que maneja el espacio en disco. Cuando se elimina un documento, en lugar de liberar inmediatamente el espacio en disco, MongoDB lo marca como eliminado y deja el espacio disponible para futuras escrituras. Esto significa que la eliminación real de los datos del disco puede llevar algún tiempo, especialmente si la colección está muy fragmentada.

    Mejores opciones

    Para eliminar los registros más antiguos de manera más eficiente, puedes probar una o más de las siguientes opciones:

    1. Particionamiento: Si tu colección tiene una clave de partición natural, como un rango de fechas, puedes particionar los datos en múltiples colecciones más pequeñas basadas en esa clave. De esta manera, puedes eliminar los datos antiguos eliminando colecciones completas, lo cual es más rápido que eliminar documentos individuales.
    2. Eliminación por lotes: En lugar de eliminar todos los documentos de una vez, puedes eliminarlos por lotes de un tamaño determinado, utilizando el método limit(). Esto puede ayudar a reducir la carga en la base de datos y hacer que el proceso de eliminación sea más manejable.

    3. Usar una consulta de rango: Si estás seguro de que el campo modifiedOn siempre aumenta, puedes utilizar una consulta de rango para eliminar todos los documentos que sean anteriores a una determinada fecha. Por ejemplo, puedes utilizar la siguiente consulta para eliminar todos los documentos que sean anteriores al 20 de diciembre de 2021:

      db.miColeccion.deleteMany({ modifiedOn: { $lt: new Date('2021-12-20T00:00:00Z') } })
      

      Esta consulta debería ser más rápida que la consulta original, ya que puede aprovechar el índice en modifiedOn.

    4. Usar mongodump y mongorestore: Otra opción es utilizar las utilidades mongodump y mongorestore para crear una copia de seguridad de los datos más recientes y luego restaurarla en una nueva colección. De esta manera, puedes descartar los datos antiguos y comenzar con una colección nueva que solo contenga los datos más recientes. Sin embargo, esta opción puede no ser práctica si el tamaño de los datos es demasiado grande.

Comments are closed.