optimizar - insertar varios documentos en mongodb
¿Por qué y cuándo es necesario reconstruir los índices en MongoDB? (2)
He estado trabajando con MongoDB por un tiempo y hoy tuve dudas mientras discutía con un colega.
La cosa es que cuando creas un índice en MongoDB, la colección se procesa y el índice se crea.
El índice se actualiza dentro de la inserción y eliminación de documentos, por lo que realmente no veo la necesidad de ejecutar una operación de reconstrucción del índice (que elimina el índice y luego lo reconstruye).
Según la documentación de MongoDB:
Normalmente, MongoDB compacta los índices durante las actualizaciones de rutina. Para la mayoría de los usuarios, el comando reIndex es innecesario. Sin embargo, puede valer la pena ejecutar si el tamaño de la colección ha cambiado significativamente o si los índices consumen una cantidad desproporcionada de espacio en disco.
¿Alguien ha tenido la necesidad de ejecutar una operación de índice de reconstrucción que valga la pena?
Según la documentación de MongoDB, generalmente no hay necesidad de reconstruir los índices de forma rutinaria.
NOTA : cualquier consejo sobre almacenamiento se vuelve más interesante con MongoDB 3.0+, que introdujo una API de motor de almacenamiento conectable . Mis comentarios a continuación se refieren específicamente al motor de almacenamiento MMAP predeterminado en MongoDB 3.0 y versiones anteriores. WiredTiger y otros motores de almacenamiento tienen diferentes implementaciones de almacenamiento para datos e índices.
Puede haber algún beneficio en la reconstrucción de un índice con el motor de almacenamiento MMAP si:
Un índice consume una cantidad de espacio mayor a la esperada en comparación con los datos. Nota: debe controlar los datos históricos y el tamaño del índice para tener una línea de base para la comparación.
Desea migrar de un formato de índice más antiguo a uno más nuevo. Si es aconsejable una reindexación, esto se mencionará en las notas de actualización. Por ejemplo, MongoDB 2.0 introdujo mejoras significativas en el rendimiento del índice, por lo que las notas de la versión incluyen una reindexación sugerida al formato v2.0 después de la actualización. De manera similar, MongoDB 2.6 introdujo
2dsphere
(v2.0) que tienen un comportamiento predeterminado diferente (dispersos por defecto). Los índices existentes no se reconstruyen después de las actualizaciones de la versión del índice; la elección de si / cuándo actualizar se deja al administrador de la base de datos.Ha cambiado el formato
_id
para una colección hacia o desde una clave monótonamente creciente (por ejemplo, ObjectID) a un valor aleatorio. Esto es un poco esotérico, pero hay una optimización de índice que divide los grupos de b-tree 90/10 (en lugar de 50/50) si está insertando_id
s que siempre están aumentando (ref: SERVER-983 ). Si la naturaleza de su_id
cambia significativamente, puede ser posible construir un b-tree más eficiente con un nuevo índice.
Para obtener más información sobre el comportamiento general del árbol B, consulte: Wikipedia: árbol B
Visualización del uso del índice
Si realmente tienes curiosidad por profundizar un poco más en el índice interno, puedes probar algunos comandos / herramientas experimentales. Espero que estos se limiten a MongoDB 2.4 y 2.6 solamente:
Si bien no conozco las razones técnicas exactas por las que, en MongoDB, puedo hacer algunas suposiciones sobre esto, en función de lo que sé sobre la indexación de otros sistemas y en base a la documentación que citó.
La idea general de un índice
Al pasar de un documento a otro, en la colección de documentos completa, hay una gran cantidad de tiempo y esfuerzo desperdiciado que pasa por alto todos los datos que no necesitan ser tratados. Si está buscando un documento con el ID "1234", tener que moverse a través de 100 K + de cada documento lo hace lento
En lugar de tener que buscar en todo el contenido de cada documento de la colección (mover físicamente las cabezas de lectura del disco, etc.), un índice lo hace rápido. Básicamente es un par de clave / valor que te da la identificación y la ubicación de ese documento. MongoDB puede escanear rápidamente todos los identificadores en el índice, encontrar las ubicaciones de los documentos que necesita y cargarlos directamente.
Asignación de tamaño de archivo para un índice
Los índices ocupan espacio en el disco porque son básicamente un par clave / valor almacenado en una ubicación mucho más pequeña. Si tiene una colección muy grande (gran cantidad de elementos en la colección), entonces su índice aumenta de tamaño.
La mayoría de los sistemas operativos asignan porciones de espacio en disco en ciertos tamaños de bloque. La mayoría de las bases de datos también asignan espacio en disco en grandes porciones, según sea necesario.
En lugar de aumentar 100K de tamaño de archivo cuando se agregan 100K de documentos, MongoDB probablemente crecerá 1MB o tal vez 10MB o algo así. No sé cuál es el tamaño de crecimiento real. En SQL Server, puede decirle qué tan rápido crecer, y MongoDB probablemente tenga algo así.
El crecimiento en trozos le da la capacidad de "hacer crecer" los documentos en el espacio más rápido porque la base de datos no necesita expandirse constantemente. Si la base de datos ahora tiene 10 MB de espacio ya asignado, solo puede utilizar ese espacio. No tiene que seguir expandiendo el archivo para cada documento. Solo tiene que escribir los datos en el archivo.
Probablemente esto sea así para las colecciones e índices de colecciones, cualquier cosa que esté almacenada en el disco.
Tamaño de archivo y reconstrucción de índice
Cuando una colección grande tiene muchos documentos agregados y eliminados, el índice se fragmenta. es posible que las claves de índice no estén en orden porque había espacio en el centro del archivo de índice y no al final, cuando se necesitaba crear el índice. Las claves de índice también pueden tener mucho espacio entre ellas.
Si hay 10,000 elementos en el índice y se debe insertar # 10,001, se puede insertar en la mitad del archivo de índice. Ahora el índice necesita reconstruirse para poner todo en orden. Esto implica mover una gran cantidad de datos para hacer espacio al final del archivo y colocar el artículo # 10,001 al final.
Si el índice se está batiendo constantemente (muchas cosas se eliminan y se agregan) es probablemente más rápido simplemente aumentar el tamaño del archivo de índice y siempre poner las cosas al final. esto es rápido para crear el índice, pero deja agujeros vacíos en el archivo donde se eliminaron las cosas antiguas.
Si el archivo de índice tiene un espacio vacío donde solían estar las cosas eliminadas, esto es un esfuerzo inútil al leer el índice. El archivo de índice tiene más movimiento del necesario para llegar al siguiente elemento del índice. Por lo tanto, el índice se repara a sí mismo ... lo que puede llevar mucho tiempo para colecciones muy grandes o cambios muy grandes en una colección.
Reconstruir para un archivo de índice grande
Puede tomar una gran cantidad de acceso a disco y operaciones de E / S para compactar correctamente el archivo de índice a un tamaño razonable, con todo en orden. Mueva los elementos fuera de lugar a la ubicación temporal, libere espacio en el lugar correcto y muévalos hacia atrás. Por cierto, para liberar espacio, tuvo que mover otros elementos a la ubicación temporal. Es recursivo y de mano dura.
Por lo tanto, si tiene una gran cantidad de elementos en una colección y esa colección tiene elementos agregados y eliminados de manera regular, es posible que el índice deba reconstruirse desde cero. Hacer esto borraría el archivo de índice actual y reconstruiría desde cero, lo que probablemente será más rápido que intentar hacer miles de movimientos dentro del archivo existente. En lugar de mover las cosas, solo las escribe secuencialmente, desde cero.
Gran cambio en el tamaño de la colección
Dando todo lo que asumo arriba, un gran cambio en el tamaño de la colección causaría este tipo de palizas. Si tiene 10,000 documentos en la colección y borra 8,000 de ellos ... bueno, ahora tiene un espacio vacío en su archivo de índice donde solían estar los 8,000 elementos. MongoDB necesita mover los 2,000 elementos restantes en el archivo físico para reconstruirlo de forma compacta.
En lugar de esperar a que se limpien 8,000 espacios vacíos, podría ser más rápido reconstruir desde cero con los 2,000 artículos restantes.
¿Conclusión? ¿Tal vez?
Por lo tanto, la documentación que citó probablemente tratará las necesidades de "big data" o las recopilaciones y los índices de alta paliza.
También tenga en cuenta que estoy haciendo una suposición basada en lo que sé acerca de la indexación, la asignación de discos, la fragmentación de archivos, etc.
Mi conjetura es que "la mayoría de los usuarios" en la documentación significa que el 99.9% o más de las colecciones de mongodb no tienen que preocuparse por esto.
Caso específico de MongoDB
Según la documentación de MongoDB:
El método remove () no elimina los índices.
Por lo tanto, si elimina documentos de una colección, está perdiendo espacio en el disco a menos que reconstruya el índice para esa colección.