2011-08-29 8 views
46

Tengo más de 300k registros en una colección en Mongo.Paginación lenta sobre toneladas de registros en mongodb

Cuando funciono con esta pregunta muy simple:

db.myCollection.find().limit(5); 

Se tarda sólo unos pocos milisegundos.

Pero cuando se utiliza omitir en la consulta:

db.myCollection.find().skip(200000).limit(5) 

No volverá nada ... que tiene una duración de minutos y no devuelve nada.

¿Cómo hacerlo mejor?

Respuesta

57

De MongoDB documentation:

Costos de paginación

Desafortunadamente saltar puede ser (muy) costosa y requiere el servidor para caminar desde el inicio de la recolección, o el índice, para llegar a la posición de desplazamiento/salto antes de que pueda comenzar a devolver la página de datos (límite). A medida que el número de página aumenta, el salto se hará más lento y requerirá más CPU, y posiblemente IO obligado, con colecciones más grandes.

La paginación basada en rangos proporciona un mejor uso de los índices pero no le permite saltar fácilmente a una página específica.

Tienes que hacerte una pregunta: ¿con qué frecuencia necesitas 40000th page? También vea el artículo this;

78

Un enfoque a este problema, si usted tiene una gran cantidad de documentos y se les está mostrando en ordenados fin (no estoy seguro de lo útil es skip si no estás) sería el uso de la tecla que se está ordenando para seleccionar la siguiente página de resultados.

Así que si usted comienza con

db.myCollection.find().limit(100).sort({created_date:true}); 

y luego extraer la fecha de creación de la última documento devuelto por el cursor en una variable max_created_date_from_last_result, se puede obtener la siguiente página con el mucho más eficiente (suponiendo usted tiene un índice en created_date) consulta

db.myCollection.find({created_date : { $gt : max_created_date_from_last_result } }).limit(100).sort({created_date:true}); 
+3

Esto parece realmente bueno. ¿Por qué no veo a más personas sugiriendo esto? – steve

+3

Bueno, es limitado, ya que solo se puede avanzar o retroceder una página a la vez, en lugar de saltar a una página específica, pero para este caso de uso limitado creo que funciona bien. – Russell

+0

idea genial. Si realmente no le importa un tipo (que no sea para este fin), y no desea ordenar o crear un índice, parece que tal vez podría omitir un paso y aprovechar el campo ObjectId (_id) que lo hará ser indexado ... es posible que los identificadores de objetos se reciclen, pero nuevamente eso no importaría en este caso. – jsh

Cuestiones relacionadas