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

MongoDb:hvordan man opretter det rigtige (sammensatte) indeks for data med mange søgbare felter

Jeg vil forsøge at forklare, hvad dette betyder med eksempel. Indekserne baseret på B-træ er ikke noget mongodb specifikt. I modsætning hertil er det et ret almindeligt koncept.

Så når du opretter et indeks - viser du databasen en nemmere måde at finde noget på. Men dette indeks er gemt et sted med en markør, der peger på en placering af det originale dokument. Disse oplysninger er ordnet, og du kan se på det som et binært træ, som har en rigtig god egenskab:søgningen er reduceret fra O(n) (lineær scanning) til O(log(n)) . Hvilket er meget meget hurtigere, fordi hver gang vi trimmer vores plads i halve (potentielt kan vi reducere tiden fra 10^6 til 20 opslag). For eksempel har vi en stor samling med feltet {a : some int, b: 'some other things'} og hvis vi indekserer det med a, ender vi med en anden datastruktur, som er sorteret efter a . Det ser sådan ud (med dette mener jeg ikke, at det er en anden samling, dette er kun til demonstration):

{a : 1, pointer: to the field with a = 1}, // if a is the smallest number in the starting collection
...
{a : 999, pointer: to the field with a = 990} // assuming that 999 is the biggest field

Så lige nu søger vi efter et felt a =18. I stedet for at gå en efter en gennem alle elementer tager vi noget i midten, og hvis det er større end 18, så deler vi den nederste del i to og tjekker elementet der . Vi fortsætter, indtil vi finder a =18. Så ser vi på markøren, og ved at vide den udtrækker vi det oprindelige felt.

Situationen med sammensat indeks er den samme (i stedet for at sortere efter et element, bestiller vi efter mange). For eksempel har du en samling:

{ "item": 5, "location": 1, "stock": 3, 'a lot of other fields' }  // was stored at position 5 on the disk
{ "item": 1, "location": 3, "stock": 1, 'a lot of other fields' }  // position 1 on the disk
{ "item": 2, "location": 5, "stock": 7, 'a lot of other fields' }  // position 3 on the disk
... huge amount of other data
{ "item": 1, "location": 1, "stock": 1, 'a lot of other fields' }  // position 9 on the disk
{ "item": 1, "location": 1, "stock": 2, 'a lot of other fields' }  // position 7 on the disk

og ønsker et indeks { "item":1, "location":1, "stock":1 }. Opslagstabellen ville se sådan ud (en gang til - dette er ikke endnu en samling, det er kun til demonstration):

{ "item": 1, "location": 1, "stock": 1, pointer = 9 }
{ "item": 1, "location": 1, "stock": 2, pointer = 7 }
{ "item": 1, "location": 3, "stock": 1, pointer = 1 }
{ "item": 2, "location": 5, "stock": 7, pointer = 3 }
.. huge amount of other data (but not necessarily here. If item would be one it would be somewhere next to items 1)
{ "item": 5, "location": 1, "stock": 3, pointer = 5 }

Se, at her er alt stort set sorteret efter emne, derefter efter placering og derefter efter pointer. På samme måde som med et enkelt indeks behøver vi ikke at scanne alt. Hvis vi har en forespørgsel, der leder efter item = 2, location = 5 and stock = 7 vi kan hurtigt identificere, hvor dokumenter med item = 2 er og derefter på samme måde hurtigt identificere hvor blandt disse varer vare med location 5 og så videre.

Og lige nu en interessant del . Vi oprettede også kun et indeks (selvom dette er et sammensat indeks, er det stadig et indeks), vi kan bruge det til hurtigt at finde elementet

  • kun ved item . Det eneste, vi behøver at gøre, er kun det første skridt. Så det nytter ikke at oprette endnu et indeks {location :1}, fordi det allerede er dækket af sammensat indeks.
  • også kan vi hurtigt kun finde efter item and by location (vi behøver kun 2 trin).

Cool 1 indeks, men hjælper os på tre forskellige måder. Men vent et øjeblik:hvad nu hvis vi vil finde efter item and stock . Åh, det ser ud til, at vi også kan fremskynde denne forespørgsel. Vi kan i log(n) finde alle elementer med specifik vare og ... her må vi stoppe - magien er færdig. Vi er nødt til at gentage dem alle sammen. Men stadig ret godt.

Men kan det hjælpe os med andre spørgsmål. Lad os se på en forespørgsel efter location som ser ud til at være allerede bestilt. Men hvis du vil se på det - ser du, at det er noget rod. En i begyndelsen og så en til sidst. Det kan slet ikke hjælpe dig.

Jeg håber, at dette afklarer nogle få ting:

  • hvorfor indekser er gode (reducer tiden fra O(n) til potentielt O(log(n))
  • hvorfor sammensatte indekser kan hjælpe med nogle forespørgsler, men vi har ikke oprettet et indeks på det pågældende felt og hjælper med nogle andre forespørgsler.
  • hvilke indekser er omfattet af sammensat indeks
  • hvorfor indekser kan skade (det skaber yderligere datastruktur, som bør vedligeholdes)

Og dette burde fortælle en anden gyldig ting:indeks er ikke en sølvkugle . Du kan ikke fremskynde alle dine forespørgsler, så det lyder dumt at tro, at ved at oprette indekser på alle felter ville ALT være super hurtigt.



  1. Gennemsnit af et underdokumentfelt på tværs af dokumenter i Mongo

  2. Sortering efter maksimalt matrixfelt, stigende eller faldende

  3. Hvordan man forespørger med flere betingelser og disse betingelser er afhængige

  4. Sådan tjekker du forbindelsen til mongodb