Ho un server Mongo in esecuzione su un VPS con 16 GB di memoria (sebbene probabilmente con IO lento che utilizza dischi magnetici).
Ho una collezione di circa 35 milioni di dischi, che non rientrano nella memoria principale (db.stats()
segnala un size
di 35 GB e un storageSize
di 14 GB), ma il 1,7 GB riportato per totalIndexSize
dovrebbe stare comodamente lì.
C'è un campo particolare bg
Sto interrogando su quale può essere presente con il valore true
o assente del tutto (per favore non discutere se questa è la migliore rappresentazione dei dati - Continuo a pensare che Mongo si comporta stranamente). Questo campo è indicizzato con un indice non sparse con una dimensione segnalata di 146 MB.
Sto utilizzando il motore di archiviazione WiredTiger con una dimensione cache predefinita (quindi dovrebbe essere di circa 8 GB).
Sto cercando di contare il numero di record mancanti nel campo bg
.
Contando true
valori è abbastanza veloci (pochi secondi):
> db.entities.find({bg: true}).count()
8300677
Tuttavia la query per i valori mancanti è estremamente lento (circa 5 minuti):
> db.entities.find({bg: null}).count()
27497706
Ai miei occhi, explain()
sembra ok:
> db.entities.find({bg: null}).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "testdb.entities",
"indexFilterSet" : false,
"parsedQuery" : {
"bg" : {
"$eq" : null
}
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"bg" : {
"$eq" : null
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"bg" : 1
},
"indexName" : "bg_1",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"bg" : [
"[null, null]"
]
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "mongo01",
"port" : 27017,
"version" : "3.0.3",
"gitVersion" : "b40106b36eecd1b4407eb1ad1af6bc60593c6105"
},
"ok" : 1
}
Tuttavia la query rimane ostinatamente lento, anche dopo ripetute chiamate. Altre query conteggio per diversi valori sono veloci:
> db.entities.find({bg: "foo"}).count()
0
> db.entities.find({}).count()
35798383
Trovo questo tipo di strano, dal momento che la mia comprensione è che i campi in indici non sparse mancanti vengono semplicemente memorizzati come null
, quindi la query conte con null
dovrebbero essere simili per contare un valore reale (o forse fino a tre volte per tre volte più valori positivi, se deve contare più voci di indice o qualcosa del genere). Effettivamente, this answer riporta vasti miglioramenti di velocità rispetto a query simili che coinvolgono i valori null
e .count()
. L'unico punto di differenziazione che posso pensare è WiredTiger.
qualcuno può spiegare perché è la mia domanda a contare i valori nulli in modo lento o che cosa posso fare per risolvere il problema (oltre a fare la sottrazione evidente delle true
conteggi del totale, che avrebbe funzionato bene, ma non avrebbe soddisfare la mia curiosità)?
Ho anche trovato questo. Il tell tell me è il filtro nella fase FETCH. Troverete quando chiedete qualcosa che manca. – msaspence