sql >> Database teknologi >  >> NoSQL >> MongoDB

Mongo Triple Compound Index

bundlinje / tl;dr: Indeks b kan "springes over" hvis a og c der søges efter lighed eller ulighed, men ikke for eksempel for sorteringer på c .

Dette er et meget godt spørgsmål. Desværre kunne jeg ikke finde noget, der autoritativt besvarer dette mere detaljeret. Jeg tror, ​​at ydeevnen af ​​sådanne forespørgsler er blevet forbedret i løbet af de sidste år, så jeg ville ikke stole på gammelt materiale om emnet.

Det hele er ret kompliceret, fordi det afhænger af selektiviteten på dine indekser, og om du spørger efter lighed, ulighed og/eller sortering, så explain() er din eneste ven, men her er nogle ting, jeg fandt:

Advarsel :Det, der kommer nu, er en blanding af eksperimentelle resultater, ræsonnement og gæt. Jeg strækker måske Kyles analogi for langt, og Jeg tager måske endda helt fejl (og uheldig, fordi mine testresultater løst matcher mit ræsonnement).

Det er klart, at indekset for A kan bruges, hvilket, afhængigt af selektiviteten af ​​A, bestemt er meget nyttigt. At 'springe over' B kan være vanskelig, eller ej. Lad os holde dette på linje med Kyles kogebogseksempel:

French
    Beef
        ...
    Chicken
        Coq au Vin
        Roasted Chicken
    Lamb
        ...
    ...

Hvis du nu beder mig finde en fransk ret kaldet "Chateaubriand", kan jeg bruge indeks A og fordi jeg ikke kender ingrediensen, bliver jeg nødt til at scanne alle retter i A . På den anden side ved jeg, at listen over retter i hver kategori er sorteret gennem indekset C , så jeg skal kun lede efter strengene, der starter med f.eks. "Cha" i hver ingrediensliste. Hvis der er 50 ingredienser, skal jeg bruge 50 opslag i stedet for kun ét, men det er meget bedre end at skulle scanne hver fransk ret!

I mine eksperimenter var antallet meget mindre end antallet af distinkte værdier i b :det så aldrig ud til at overstige 2. Jeg testede dog kun dette med en enkelt samling, og det har sandsynligvis at gøre med selektiviteten af ​​b -indeks.

Hvis du bad mig om at give dig en alfabetisk sorteret liste over alle franske retter , men jeg ville være i problemer . Nu indekset på C er værdiløs, bliver jeg nødt til at flette-sortere alle disse indekslister. Jeg bliver nødt til at scanne hvert element for at gøre det.

Dette afspejles i mine tests. Her er nogle forenklede resultater. Den originale samling har datotider, ints og strenge, men jeg ville gerne holde tingene enkle, så det er nu alle ints.

Grundlæggende er der kun to klasser af forespørgsler:dem, hvor nscanned <=2 * limit , og dem der skal scanne hele samlingen (120k dokumenter). Indekset er {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 }});

Dit kilometertal vil variere.



  1. MongoDB:Find minimumselementet i array og slet det

  2. Kom godt i gang med MongoDB User Management

  3. Sådan finder du MongoDB feltnavn på vilkårlig dybde

  4. MongoDB-forespørgsel på udfyldte felter