sql >> Databasteknik >  >> NoSQL >> MongoDB

Mongo Triple Compound Index

bottom line / tl;dr: Index b kan "hoppas över" om a och c frågas efter jämlikhet eller ojämlikhet, men inte, till exempel, för sorteringar på c .

Det här är en mycket bra fråga. Tyvärr kunde jag inte hitta något som auktoritativt besvarar detta mer detaljerat. Jag tror att prestandan för sådana frågor har förbättrats under de senaste åren, så jag skulle inte lita på gammalt material om ämnet.

Det hela är ganska komplicerat eftersom det beror på selektiviteten på dina index och om du frågar efter jämlikhet, ojämlikhet och/eller sortering, så explain() är din enda vän, men här är några saker jag hittade:

Varning :Det som kommer nu är en blandning av experimentella resultat, resonemang och gissningar. Jag kanske sträcker ut Kyles liknelse för långt, och Jag kan till och med ha helt fel (och otur, eftersom mina testresultat löst matchar mitt resonemang).

Det är tydligt att indexet för A kan användas, vilket, beroende på selektiviteten hos A, verkligen är till stor hjälp. Att 'hoppa över' B kan vara knepigt, eller inte. Låt oss behålla detta liknande Kyles kokboksexempel:

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

Om du nu ber mig hitta någon fransk maträtt som heter "Chateaubriand", kan jag använda index A och eftersom jag inte känner till ingrediensen måste jag skanna alla rätter i A . Å andra sidan vet jag att listan över rätter i varje kategori sorteras genom indexet C , så jag behöver bara leta efter strängarna som börjar med, säg, "Cha" i varje ingredienslista. Om det finns 50 ingredienser kommer jag att behöva 50 uppslag istället för bara en, men det är mycket bättre än att behöva skanna varje fransk maträtt!

I mina experiment var antalet mycket mindre än antalet distinkta värden i b :det verkade aldrig överstiga 2. Men jag testade detta bara med en enda samling, och det har förmodligen att göra med selektiviteten för b -index.

Om du bad mig ge dig en alfabetiskt sorterad lista över alla franska rätter , men jag skulle ha problem . Nu indexet på C är värdelös, skulle jag behöva slå samman-sortera alla dessa indexlistor. Jag måste skanna alla element för att göra det.

Detta återspeglas i mina tester. Här är några förenklade resultat. Den ursprungliga samlingen har datum och tider, ints och strängar, men jag ville hålla saker och ting enkla, så det är nu alla ints.

I huvudsak finns det bara två klasser av frågor:de där nscanned <=2 * limit , och de som måste skanna hela samlingen (120k dokument). Indexet är {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 }});

Din körsträcka kommer att variera.



  1. Redis på Azure Performance Benchmark – ScaleGrid för Redis™ kontra Azure Cache

  2. MongoDB bästa praxis för referenser

  3. Fel:getaddriinfo ENOTFOUND i nodejs for get call

  4. Java Mongodb nummerlång fråga