sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDb:hur man skapar rätt (sammansatt) index för data med många sökbara fält

Jag ska försöka förklara vad detta betyder med exempel. Indexen baserade på B-träd är inte något mongodb-specifikt. Däremot är det ganska vanligt begrepp.

Så när du skapar ett index - visar du databasen ett enklare sätt att hitta något. Men detta index lagras någonstans med en pekare som pekar på en plats för originaldokumentet. Denna information är ordnad och du kan se den som ett binärt träd som har en riktigt bra egenskap:sökningen reduceras från O(n) (linjär skanning) till O(log(n)) . Vilket är mycket mycket snabbare eftersom vi halverar vårt utrymme varje gång (potentiellt kan vi minska tiden från 10^6 till 20 uppslagningar). Vi har till exempel en stor samling med fältet {a : some int, b: 'some other things'} och om vi indexerar den med a, får vi en annan datastruktur som sorteras efter a . Det ser ut så här (med detta menar jag inte att det är en annan samling, detta är bara för 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å just nu söker vi efter ett fält a =18. Istället för att gå en och en genom alla element tar vi något i mitten och om det är större än 18, så delar vi den nedre delen på mitten och kontrollerar elementet där . Vi fortsätter tills vi hittar a =18. Sedan tittar vi på pekaren och vet att vi extraherar det ursprungliga fältet.

Situationen med sammansatt index är liknande (istället för att sortera efter ett element beställer vi efter många). Du har till exempel 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

och vill ha ett index { "artikel":1, "plats":1, "lager":1 }. Uppslagstabellen skulle se ut så här (en gång till - det här är inte en annan samling, det här är bara för 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 att här är allt i princip sorterat efter objekt, sedan efter plats och sedan efter pekare. På samma sätt som med ett enda index behöver vi inte skanna allt. Om vi ​​har en fråga som letar efter item = 2, location = 5 and stock = 7 vi kan snabbt identifiera var dokument med item = 2 är och sedan på samma sätt snabbt identifiera var bland dessa objekt objekt med location 5 och så vidare.

Och just nu en intressant del . Vi skapade också bara ett index (även om detta är ett sammansatt index, är det fortfarande ett index) vi kan använda det för att snabbt hitta elementet

  • endast av item . Allt vi behöver göra är egentligen bara det första steget. Så det är ingen idé att skapa ett annat index {plats :1} eftersom det redan täcks av sammansatt index.
  • Vi kan också snabbt hitta endast efter item and by location (vi behöver bara 2 steg).

Coolt 1 index men hjälper oss på tre olika sätt. Men vänta lite:tänk om vi vill hitta efter item and stock . Åh, det verkar som att vi kan snabba upp den här frågan också. Vi kan i log(n) hitta alla element med ett specifikt objekt och ... här måste vi sluta - magin är över. Vi måste upprepa dem alla. Men ändå ganska bra.

Men kan det hjälpa oss med andra frågor. Låt oss titta på en fråga efter location som ser ut att redan ha beställts. Men om du ska titta på det - ser du att det här är en röra. En i början och sedan en i slutet. Det kan inte hjälpa dig alls.

Jag hoppas att detta klargör några saker:

  • varför index är bra (minska tiden från O(n) till potentiellt O(log(n))
  • varför sammansatta index kan hjälpa till med vissa frågor, men vi har inte skapat ett index för det specifika fältet och hjälper till med vissa andra frågor.
  • vilka index omfattas av sammansatt index
  • varför index kan skada (det skapar ytterligare datastruktur som bör underhållas)

Och detta borde berätta en annan sak:index är inte en silverkula . Du kan inte snabba upp alla dina frågor, så det låter dumt att tro att genom att skapa index på alla fält skulle ALLT gå supersnabbt.



  1. Diakritisk skiftlägeskänslig sökning Loopback

  2. arv i dokumentdatabas?

  3. Slår samman matrisfält i MongoDB-aggregation

  4. Importera CSV-fil (innehåller några icke-UTF8-tecken) i MongoDb