Ditt observerade prestandaproblem vid en första fråga är sannolikt ett av följande problem (i ungefärlig ordning efter sannolikhet):
1) Din applikation/webbtjänst har vissa overhead att initiera på första begäran (dvs. allokera minne, konfigurera anslutningspooler, lösa DNS, ...).
2) Index eller data som du har begärt finns ännu inte i minnet, så de måste laddas.
3) Frågeoptimeraren kan ta lite längre tid att köra på den första begäran, eftersom den jämför planexekveringen för ditt frågemönster.
Det skulle vara till stor hjälp att testa frågan via mongo
skal och isolera om overheaden är relaterad till MongoDB eller din webbtjänst (snarare än att tajma båda, som du har gjort).
Följande är några anteckningar relaterade till MongoDB.
Cachning
MongoDB har ingen "cachetid" för dokument i minnet. Den använder minnesmappade filer för disk I/O och dokumenten i minnet är baserade på dina aktiva frågor (dokument/index som du nyligen har laddat) samt tillgängligt minne. Operativsystemets virtuella minneshanterare är ansvarig för cache , och kommer vanligtvis att följa en LRU-algoritm (Last-Recently Used) för att bestämma vilka sidor som ska bytas ut från minnet.
Minnesanvändning
Det förväntade beteendet är att MongoDB med tiden kommer att växa till att använda allt ledigt minne för att lagra din aktiva arbetsdatauppsättning.
Tittar på din angivna db.stats()
siffror (och förutsatt att det är ditt enda). databas), ser det ut som att din databasstorlek är aktuell på cirka 1 Gb så du bör kunna hålla allt inom ditt 10 Gb totala RAM-minne om inte:
- det finns andra processer som konkurrerar om minnet
- du har startat om din
mongod
servern och dessa dokument/index har inte begärts ännu
I MongoDB 2.2 finns en ny touch
kommando som du kan använda för att ladda index eller dokument till minnet efter en omstart av servern. Detta bör endast användas vid första uppstart för att "värma upp" servern, eftersom du annars utan hjälp kan tvinga ut faktisk "aktiv" data ur minnet.
På ett linux-system, till exempel, kan du använda top
kommandot och bör se att:
- virtuella bytes/VSIZE tenderar att vara storleken på hela databasen
- om servern inte har andra processer igång, kommer inbyggda bytes/RSIZE att vara maskinens totala minne (detta inkluderar innehållet i filsystemets cache)
mongod
ska inte använda swap (eftersom filerna är minnesmappade)
Du kan använda mongostat
verktyg för att få en snabb bild av din mongod
aktivitet .. eller mer användbart, använd en tjänst som MMS
för att övervaka mätvärden över tid.
Frågeoptimerare
MongoDB Frågeoptimeraren
jämför planexekveringen för ett frågemönster var ~1 000 skrivoperation och cachar sedan den "vinnande" frågeplanen tills nästa gång optimeraren körs .. eller så anropar du uttryckligen en explain()
på den frågan.
Det här borde vara enkelt att testa:kör din fråga i mongo
skal med .explain()
och titta på ms-timingerna, och även antalet indexposter och skannade dokument. Tidpunkten för en explain() är inte den faktiska tid det tar för frågorna att köras, eftersom det inkluderar kostnaden för att jämföra planerna. Den typiska exekveringen kommer att vara mycket snabbare .. och du kan leta efter långsamma frågor i din mongod
log.
Som standard loggar MongoDB alla frågor långsammare än 100 ms, så detta ger en bra utgångspunkt för att leta efter frågor att optimera. Du kan justera det långsamma ms-värdet med --slowms
config-alternativet, eller använd Database Profiler
kommandon.