sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB Compound Index - Spelar sorteringsordningen någon roll?

Du kan tänka på MongoDB enfältsindex som en array, med pekare till dokumentplatser. Till exempel, om du har en samling med (observera att sekvensen är avsiktligt ur funktion):

[collection]
1: {a:3, b:2}
2: {a:1, b:2}
3: {a:2, b:1}
4: {a:1, b:1}
5: {a:2, b:2}

Enkelfältsindex

Om du nu gör det:

db.collection.createIndex({a:1})

Indexet ser ungefär ut så här:

[index a:1]
1: {a:1} --> 2, 4
2: {a:2} --> 3, 5
3: {a:3} --> 1

Notera tre viktiga saker:

  • Det är sorterat efter a stigande
  • Varje post pekar på platsen där de relevanta dokumenten finns
  • Indexet registrerar bara värdena för a fält. b fältet finns inte alls i indexet

Så om du gör en fråga som:

db.collection.find().sort({a:1})

Allt den behöver göra är att gå indexet uppifrån och ned, hämta och mata ut dokumentet som posterna pekar på. Observera att du också kan gå indexet från botten, t.ex.:

db.collection.find().sort({a:-1})

och den enda skillnaden är att du går indexet baklänges.

Eftersom b inte finns i indexet alls, kan du inte använda indexet när du frågar något om b .

Sammansatt index

I ett sammansatt index, t.ex.:

db.collection.createIndex({a:1, b:1})

Det betyder att du vill sortera efter a först, sortera sedan efter b . Indexet skulle se ut så här:

[index a:1, b:1]
1: {a:1, b:1} --> 4
2: {a:1, b:2} --> 2
3: {a:2, b:1} --> 3
4: {a:2, b:2} --> 5
5: {a:3, b:2} --> 1

Observera att:

  • Indexet är sorterat från a
  • Inom varje a du har en sorterad b
  • Du har 5 indexposter jämfört med bara tre i det föregående exemplet med ett fält

Med detta index kan du göra en fråga som:

db.collection.find({a:2}).sort({b:1})

Det kan lätt hitta var a:2 gå sedan indexet framåt. Med tanke på det indexet kan du inte göra :

db.collection.find().sort({b:1})
db.collection.find({b:1})

I båda frågorna kan du inte enkelt hitta b eftersom den är spridd över hela indexet (dvs inte i sammanhängande poster). Hur du än kan gör:

db.collection.find({a:2}).sort({b:-1})

eftersom du i princip kan hitta var a:2 är och gå b poster bakåt.

Redigera :förtydligande av @marcospgps fråga i kommentaren:

Möjligheten att använda indexet {a:1, b:1} för att tillfredsställa find({a:2}).sort({b:-1}) faktiskt vettigt om du ser det från en sorterad tabellsynpunkt. Till exempel indexet {a:1, b:1} kan ses som:

a | b
--|--
1 | 1
1 | 2
2 | 1
2 | 2
2 | 3
3 | 1
3 | 2

find({a:2}).sort({b:1})

Indexet {a:1, b:1} betyder sort by a, then within each a, sort the b values . Om du sedan gör en find({a:2}).sort({b:1}) , indexet vet var alla a=2 är. Inom detta block av a=2 , b skulle sorteras i stigande ordning (enligt indexspecifikationen), så att frågan find({a:2}).sort({b:1}) kan tillfredsställas av:

a | b
--|--
1 | 1
1 | 2
2 | 1 <-- walk this block forward to satisfy
2 | 2 <-- find({a:2}).sort({b:1})
2 | 3 <--
3 | 1
3 | 2

find({a:2}).sort({b:-1})

Eftersom indexet kan gå framåt eller bakåt, följdes en liknande procedur, med en liten vridning i slutet:

a | b
--|--
1 | 1
1 | 2
2 | 1  <-- walk this block backward to satisfy
2 | 2  <-- find({a:2}).sort({b:-1})
2 | 3  <--
3 | 1
3 | 2

Det faktum att indexet kan gå framåt eller bakåt är nyckeln som möjliggör frågan find({a:2}).sort({b:-1}) för att kunna använda indexet {a:1, b:1} .

Frågeplaneraren förklarar

Du kan se vad frågeplaneraren planerar genom att använda db.collection.explain().find(....) . I grund och botten om du ser en stage av COLLSCAN , inget index användes eller kan användas för frågan. Se förklara resultat för detaljer om kommandots utdata.



  1. Mongodb/mongoose insert är inte en funktion

  2. Hur kan jag få maxvärde i kapslade dokument?

  3. hur man kontrollerar om ett dokument är uppdaterat eller infogat i MongoDB

  4. moveChunk misslyckades med att koppla TO-shard i dataöverföringen:kan inte acceptera nya bitar eftersom