bottom line / tl;dr: Index b
kan worden 'overgeslagen' als a
en c
worden opgevraagd voor gelijkheid of ongelijkheid, maar bijvoorbeeld niet voor sorteringen op c
.
Dit is een zeer goede vraag. Helaas kon ik niets vinden dat dit op gezaghebbende wijze in meer detail beantwoordt. Ik geloof dat de prestaties van dergelijke zoekopdrachten de afgelopen jaren zijn verbeterd, dus ik zou oud materiaal over dit onderwerp niet vertrouwen.
Het geheel is nogal ingewikkeld omdat het afhangt van de selectiviteit op je indexen en of je zoekt naar gelijkheid, ongelijkheid en/of sortering, dus explain()
is je enige vriend, maar hier zijn enkele dingen die ik heb gevonden:
Voorbehoud :Wat nu komt is een mengeling van experimentele resultaten, redeneren en gissen. Ik trek Kyle's analogie misschien te ver door, en Misschien heb ik het zelfs helemaal mis (en pech, want mijn testresultaten komen losjes overeen met mijn redenering).
Het is duidelijk dat de index van A kan worden gebruikt, wat, afhankelijk van de selectiviteit van A, zeker erg nuttig is. 'Overslaan' B kan lastig zijn, of niet. Laten we dit vergelijkbaar houden met Kyle's kookboekvoorbeeld:
French
Beef
...
Chicken
Coq au Vin
Roasted Chicken
Lamb
...
...
Als je me nu vraagt om een Frans gerecht genaamd "Chateaubriand" te vinden, kan ik index A
gebruiken en omdat ik het ingrediënt niet ken, zal ik alle gerechten in A
. moeten scannen . Aan de andere kant weet ik wel dat de lijst met gerechten in elke categorie wordt gesorteerd via de index C
, dus ik hoef alleen maar te zoeken naar de tekenreeksen die beginnen met, laten we zeggen, "Cha" in elke ingrediëntenlijst. Als er 50 ingrediënten zijn, heb ik 50 zoekopdrachten nodig in plaats van slechts één, maar dat is een stuk beter dan elk Frans gerecht te moeten scannen!
In mijn experimenten was het aantal een stuk kleiner dan het aantal verschillende waarden in
b
:het leek nooit boven de 2 uit te komen. Ik heb dit echter alleen getest met een enkele verzameling, en het heeft waarschijnlijk te maken met de selectiviteit van deb
-index.
Als je me zou vragen om je een alfabetisch gesorteerde lijst te geven van alle Franse gerechten , maar ik zou in problemen zitten . Nu de index op C
waardeloos is, zou ik al die indexlijsten moeten samenvoegen en sorteren. Ik zal elk element moeten scannen om dit te doen.
Dit komt tot uiting in mijn tests. Hier zijn enkele vereenvoudigde resultaten. De originele collectie heeft datums, ints en strings, maar ik wilde het simpel houden, dus het is nu allemaal ints.
In wezen zijn er slechts twee soorten zoekopdrachten:die waarbij nscanned
<=2 * limit
, en degenen die de hele collectie moeten scannen (120k documenten). De index is {a, b, c}
:
// fast (range query on c while skipping b)
> db.Test.find({"a" : 43, "c" : { $lte : 45454 }});
// slow (sorting)
> db.Test.find({"a" : 43, "c" : { $lte : 45454 }}).sort({ "c" : -1});
> db.Test.find({"a" : 43, "c" : { $lte : 45454 }}).sort({ "b" : -1});
// fast (can sort on c if b included in the query)
> db.Test.find({"a" : 43, "b" : 7887, "c" : { $lte : 45454 }}).sort({ "c" : -1});
// fast (older tutorials claim this is slow)
> db.Test.find({"a" : {$gte : 43}, "c" : { $lte : 45454 }});
Uw kilometerstand zal variëren.