2011-08-29 9 views
46

Ho più di 300k record in una raccolta in Mongo.Impaginazione lenta su tonnellate di record in mongodb

Quando ho eseguito questo semplice query:

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

e bastano pochi millisecondi.

Ma quando uso saltare nella query:

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

Non restituirà nulla ... Si corre per i minuti e non restituisce nulla.

Come migliorare?

risposta

57

Da MongoDB documentation:

Costi Paging

Purtroppo saltare può essere (molto) costoso e richiede il server di camminare a partire dall'inizio della raccolta, o indice, per arrivare al offset/saltare la posizione prima di poter iniziare a restituire la pagina di dati (limite). Man mano che il numero di pagina aumenta, il salto diventerà più lento e più intensivo in cpu, e possibilmente vincolato all'IO, con raccolte più grandi.

Il paging basato sull'intervallo fornisce un uso migliore degli indici ma non consente di passare facilmente a una pagina specifica.

Devi farti una domanda: quanto spesso hai bisogno di 40000 ° pagina? Vedi anche articolo this;

78

Un approccio a questo problema, se si dispone di grandi quantità di documenti e li stanno visualizzando a ordinato ordine (non sono sicuro di quanto sia utile skip è se non sei) sarebbe quella di utilizzare la chiave Stai ordinando per selezionare la pagina successiva dei risultati.

Quindi, se si inizia con

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

e poi estrarre la data di creazione dell'ultimo documento restituita dal cursore in una variabile max_created_date_from_last_result, è possibile ottenere la pagina successiva con il molto più efficiente (presumendo hai un indice su created_date) query

+3

Questo sembra davvero buono. Perché non vedo più persone che lo suggeriscono? – steve

+3

Beh, è ​​limitato dal fatto che puoi andare avanti o indietro di una pagina alla volta, invece di saltare ad una pagina specifica, ma per questo caso d'uso limitato penso che funzioni bene. – Russell

+0

Fantastica idea. Se non ti interessa davvero un tipo (se non per questo scopo) e non vuoi ordinare o creare un indice, sembra che potresti saltare un passaggio e approfittare del campo ObjectId (_id) che essere indicizzato ... è possibile che gli oggetti oggetto vengano riciclati, ma anche in questo caso non sarebbe importante. – jsh

Problemi correlati