Givet en vanlig standardfråga (utan limit()
eller sort()
eller något fint tillämpat) som har ett filtervillkor på två fält (som i name
och age
i ditt exempel), för att hitta de resulterande dokumenten kommer MongoDB antingen:
- gör en fullständig samlingsskanning (läs alla dokument i hela samlingen, analysera BSON, hitta värdena i fråga, testa dem mot indata och returnera/kassera varje dokument):Detta är super I/O-intensivt och därför långsamt.
- använd ett index som innehåller ett av fälten (använd indexträd för att hitta relevant delmängd av dokument följt av en skanning av dem):Beroende på din datadistribution/indexselektivitet kan detta vara mycket snabbt eller knappt ge någon fördel (föreställ dig ett index på
age
i en datauppsättning av miljontals människor mellan 30 och 40 år --> skulle varje uppslagning fortfarande ge ett oändligt antal dokument). - använd två index som tillsammans innehåller båda fälten i fråga (ladda in båda indexen, utför nyckelsökningar och beräkna sedan skärningspunkten för resultaten):Återigen, beroende på din datadistribution, kanske detta ger dig bättre(re) prestanda. Det bör dock i de flesta fall vara snabbare än #2. Jag skulle dock bli förvånad om det verkligen var 10 gånger långsammare än #4 (som du nämnde).
- använd ett sammansatt index (två efterföljande nyckelsökningar leder omedelbart till de nödvändiga dokumenten):Detta kommer att vara det snabbaste alternativet av alla med tanke på att det kräver minsta och billigaste operationer för att komma till rätt dokument. För att säkerställa största möjliga återanvändning (inte prestanda som inte kommer att påverkas av detta) bör du i allmänhet börja med det mest selektiva fältet först, så i ditt fall förmodligen
name
och inteage
med tanke på att många människor kommer att ha sammaage
(så låg selektivitet) jämfört medname
(högre selektivitet). Men det valet beror också på ditt konkreta scenario och de frågor du tänker köra mot din databas. Det finns en ganska bra artikel på webben om hur man bäst definierar ett sammansatt index med hänsyn till olika aspekter av din specifika situation:https://emptysqua.re/blog/optimizing-mongodb-compound-indexes
Andra aspekter att tänka på är:Indexuppdateringar kommer till ett visst pris. Men om allt du bryr dig om är obearbetad läshastighet och du bara har några få uppdateringar då och då, bör du satsa på fler/större index.
Och sist men inte minst (!) det väl överanvända rådet:Profilera ditt system med riktiga data och kanske till och med realistiska belastningsscenarier. Och fortsätt även att mäta allt eftersom dina data/system förändras över tiden.
Ytterligare läsning:https://docs.mongodb.com/manual/core/query-optimization/index.html
https://dba.stackexchange.com/questions/158240/mongodb-index-intersection-does-not-eliminate-the-need-for-creating-compound-in
Index skärningspunkt kontra sammansatt index?
mongodb compund index vs. index intersect
Hur spelar ordningen på sammansatta index roll i MongoDB prestandamässigt?
I MongoDB använder jag en stor fråga, hur jag skapar ett sammansatt index eller enstaka index, så min svarstid ökar