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

MongoDB Compound Indexes - Betyder sorteringsrækkefølgen noget?

Du kan tænke på MongoDB enkeltfeltsindeks som et array med pointere til dokumentplaceringer. For eksempel, hvis du har en samling med (bemærk, at sekvensen bevidst er ude af rækkefølge):

[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}

Enkeltfeltsindeks

Hvis du nu gør det:

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

Indekset ser omtrent sådan ud:

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

Bemærk tre vigtige ting:

  • Det er sorteret efter a stigende
  • Hver indtastning peger på det sted, hvor de relevante dokumenter ligger
  • Indekset registrerer kun værdierne af a Mark. b felt findes slet ikke i indekset

Så hvis du laver en forespørgsel som:

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

Alt det skal gøre er at gå indekset fra top til bund, hente og udskrive det dokument, som indtastningerne peger på. Bemærk, at du også kan gå i indekset fra bunden, f.eks.:

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

og den eneste forskel er, at du går indekset omvendt.

Fordi b er slet ikke i indekset, kan du ikke bruge indekset, når du forespørger noget om b .

Sammensat indeks

I et sammensat indeks f.eks.:

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

Det betyder, at du vil sortere efter a først, sorter derefter efter b . Indekset ville se sådan ud:

[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

Bemærk at:

  • Indekset er sorteret fra a
  • Inden for hver a du har en sorteret b
  • Du har 5 indeksindgange i forhold til kun tre i det foregående enkeltfeltseksempel

Ved at bruge dette indeks kan du lave en forespørgsel som:

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

Det kan nemt finde hvor a:2 gå derefter indekset frem. I betragtning af det indeks kan du ikke gøre det :

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

I begge forespørgsler kan du ikke nemt finde b da det er spredt over hele indekset (dvs. ikke i sammenhængende poster). Men du kan gør:

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

da du i det væsentlige kan finde hvor a:2 er, og gå b indtastninger baglæns.

Rediger :præcisering af @marcospgps spørgsmål i kommentaren:

Muligheden for at bruge indekset {a:1, b:1} for at tilfredsstille find({a:2}).sort({b:-1}) giver faktisk mening, hvis du ser det fra et sorteret bordsynspunkt. For eksempel indekset {a:1, b:1} kan opfattes som:

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

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

Indekset {a:1, b:1} betyder sort by a, then within each a, sort the b values . Hvis du derefter laver en find({a:2}).sort({b:1}) , indekset ved, hvor alle a=2 er. Inden for denne blok af a=2 , b ville blive sorteret i stigende rækkefølge (i henhold til indeksspecifikationen), så forespørgslen find({a:2}).sort({b:1}) kan tilfredsstilles ved:

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})

Da indekset kan gås frem eller tilbage, blev en lignende procedure fulgt, med en lille drejning i slutningen:

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, at indekset kan gås frem eller tilbage, er nøglepunktet, der aktiverer forespørgslen find({a:2}).sort({b:-1}) for at kunne bruge indekset {a:1, b:1} .

Forklaring af forespørgselsplanlægning

Du kan se, hvad forespørgselsplanlæggeren planlægger ved at bruge db.collection.explain().find(....) . Grundlæggende hvis du ser et stage af COLLSCAN , intet indeks blev brugt eller kan bruges til forespørgslen. Se forklar resultater for detaljer om kommandoens output.



  1. Loop udsender ikke sand eller falsk baseret på forespørgsel

  2. Samlingsbaseret multitenancy med Spring Data MongoDB

  3. Slet indlejrede felter fra alle/flere dokumenter i en samling - NodeJS + MongoDB

  4. MongoDB-ydelsesproblem:Enkelt kæmpe samling vs flere små samlinger