2011-10-05 11 views
46

Actualmente estoy usando MongoDB con millones de registros de datos. Descubrí una cosa que es bastante molesta.MongoDB 'count()' es muy lento. ¿Cómo podemos refinar/trabajar con eso?

Cuando uso la función 'count()' con una pequeña cantidad de recopilación de datos consultados, es muy rápido. Sin embargo, cuando la recopilación de datos consultados contiene miles o incluso millones de registros de datos, todo el sistema se vuelve muy lento.

Me aseguré de haber indexado los campos obligatorios.

¿Alguien ha encontrado algo idéntico? ¿Cómo haces para mejorar eso?

Respuesta

25

Ahora hay otra optimización que crear el índice adecuado.

db.users.ensureIndex({name:1}); 
db.users.find({name:"Andrei"}).count(); 

Si necesita algunos contadores, le sugiero que los precalcule cada vez que sea posible. Al utilizar la operación atómica $inc y no utilizar count({}) en absoluto.

Pero chicos mongodb que trabajan duro en mongodb, por lo que, count({}) mejoras que están planeando en mongodb 2.1 de acuerdo con la jira bug.

+0

gracias por la respuesta. Sin embargo, digamos que me gustaría filtrar los registros de datos y contar el número de registro. En este caso, $ inc no me ayuda mucho, ¿verdad? –

+0

@ WinstonChen: depende de su filtro. Proporcione un ejemplo que responderé. –

+1

Gracias. Digamos que tengo millones de registros como este: {_ id: "hash_code_here", bookname: "Los cuatro pasos para la Epifanía", autor: "Steven-Gary-Blank", categoría: 10}. Tengo aproximadamente 1 millón de libros cuya categoría es 10 y la misma categoría 9, 8, 7, etc. Tengo una página con una función de búsqueda que filtra y muestra a mis visitantes todos los libros con categoría 10 o 9, o 8 o 7 ... Se supone que la categoría es uno de los criterios en el filtro. Los visitantes también pueden agregar criterios de "autor" u otros criterios. ¿Cómo podría implementarlo con $ inc? –

10

Puede asegurarse de que el índice realmente se utiliza sin ningún acceso al disco.

Digamos que desea contar los registros con el nombre: "Andrei"

Se asegura índice en nombre (como lo ha hecho) y

db.users.find({name:"andrei"}, {_id:0, name:1}).count() 

se puede comprobar que es el más rápido forma de contar (excepto con la precomputación) marcando si

db.users.find({name:"andrei"}, {_id:0, name:1}).explain() 

muestra un campo index_only establecido en verdadero.

Este truco asegurará que su consulta recuperará registros solo de ram (índice) y no del disco.

+0

Si MongoDB decide que no debería 'hacer' index_only' para una operación como 'count', de manera predeterminada, entonces eso me suena bastante parecido a un error. – kizzx2

+0

fue cierto en 2011, tal vez esto ha cambiado con https://jira.mongodb.org/browse/SERVER-1752 – kamaradclimber

3

Por el momento no tiene mucha suerte, contar en mongodb es horrible y no mejorará en el futuro cercano. Ver: https://jira.mongodb.org/browse/SERVER-1752

Por experiencia, casi nunca deberías usarlo a menos que sea una cosa única, algo que ocurre muy raramente, o tu base de datos es bastante pequeña.

Como dijo @Andrew Orsich, use contadores siempre que sea posible (la caída a los contadores es el bloqueo de escritura global, pero mejor que count() independientemente).

3

Para mí, la solución fue cambiar el índice a escaso. Depende de una situación específica, solo pruébalo si puedes.

db.Account.createIndex({ "date_checked_1": 1 }, { sparse: true }) 

db.Account.find({  
    "dateChecked" : { $exists : true }  
}).count() 

318 miles de registros en la colección

  • 0,31 sec - con índice disperso
  • 0.79 segundos - con índice no disperso