Er komen een paar strategieën in me op:
1) Gebruik een aparte collectie/database voor de 'hot' documenten.
Als u weet welke documenten zich in de hot set bevinden, kan het helpen om ze naar een aparte collectie te verplaatsen. Dit zorgt ervoor dat de hot-documenten co-resident zijn op dezelfde extensies/pagina's. Het zorgt er ook voor dat de index voor die documenten waarschijnlijk volledig in het geheugen staat. Dit komt doordat hij kleiner is en (helemaal?) vaker wordt gebruikt.
Als de hot-documenten willekeurig worden gemengd met andere documenten, moet u waarschijnlijk fouten maken in meer van de bladelementen van de B-Tree-index bij het laden van een document, aangezien de kans dat een ander document onlangs het indexblok heeft geladen of geopend, klein is.
2) Verkort de geïndexeerde waarden .
Hoe korter de indexwaarde, hoe meer waarden er in een enkel B-Tree-blok passen. (Opmerking:de sleutels zijn niet opgenomen in de index.) Hoe meer items in een enkele bucket, hoe minder buckets en minder totaal geheugen nodig voor de index. Dat vertaalt zich naar de hogere waarschijnlijkheid / langere levensduur dat blokken in het geheugen blijven. In uw voorbeeld is een vermindering van 20->8 tekens een besparing die beter is dan 50%. Als je die 8 bytes naar een long kunt converteren, is er iets meer besparing omdat longs geen lengteprefix (4 bytes) en een volgnul hebben (5 bytes in totaal).
3) Kort de namen van de toetsen in.
Hoe korter de veldnamen, hoe minder ruimte elk document in beslag neemt. Dit heeft als ongelukkig neveneffect dat de leesbaarheid afneemt.
4) Scherf
Dit is echt de enige manier om de prestaties op peil te houden in het licht van leesbewerkingen over een heel corpus dat geheugen en eventuele schijfbandbreedte uitput. Als je shard doet, wil je nog steeds de 'hot' collectie sharden.
5) Pas de read-ahead op schijf aan naar een kleine waarde.
Aangezien de 'niet-hot' reads een willekeurig document van schijf laden, willen we eigenlijk alleen dat document lezen/in het geheugen opslaan en zo min mogelijk van de documenten eromheen. De meeste systemen zullen proberen een groot gegevensblok vooruit te lezen zodra een gebruiker een deel van een bestand leest. Dit is precies het tegenovergestelde van wat we willen.
Als u ziet dat uw systeem veel fouten maakt, maar het interne geheugen voor het mongod-proces het beschikbare systeemgeheugen niet benadert, ziet u waarschijnlijk het effect van het lezen van nutteloze gegevens door het besturingssysteem.
6) Probeer monotoon toenemende waarden voor de toetsen te gebruiken.
Dit activeert een optimalisatie (voor op ObjectId gebaseerde indexen) die, wanneer het indexblok wordt gesplitst, dit doet op 90/10 in plaats van 50/50. Het resultaat is dat de meeste blokken in uw index bijna vol zijn en u er minder nodig zult hebben.
Als u de 'hot' 50.000 documenten pas achteraf kent, zal het toevoegen van deze aan de aparte collectie in indexvolgorde ook deze optimalisatie activeren.
Rob.