sql >> Database >  >> NoSQL >> MongoDB

MongoDb:hoe maak je de juiste (samengestelde) index voor data met veel doorzoekbare velden

Ik zal proberen uit te leggen wat dit betekent door een voorbeeld. De indexen op basis van B-tree zijn niet iets mongodb-specifiek. Het is daarentegen een vrij algemeen concept.

Dus wanneer u een index maakt, laat u de database een gemakkelijkere manier zien om iets te vinden. Maar deze index wordt ergens opgeslagen met een aanwijzer die naar een locatie van het originele document wijst. Deze informatie is geordend en je zou het kunnen zien als een binaire boom die een hele mooie eigenschap heeft:de zoekopdracht wordt teruggebracht van O(n) (lineaire scan) naar O(log(n)) . Dat is veel sneller, want elke keer dat we onze ruimte in tweeën knippen (mogelijk kunnen we de tijd verkorten van 10^6 naar 20 opzoekingen). We hebben bijvoorbeeld een grote verzameling met veld {a : some int, b: 'some other things'} en als we het indexeren met a, krijgen we een andere gegevensstructuur die is gesorteerd op a . Het ziet er zo uit (hiermee bedoel ik niet dat het een andere collectie is, dit is alleen voor demonstratie):

{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

Dus op dit moment zoeken we naar een veld a =18. In plaats van één voor één door alle elementen te gaan, nemen we iets in het midden en als het groter is dan 18, dan delen we het onderste deel in tweeën en controleren het element daar . We gaan door totdat we a =18 vinden. Dan kijken we naar de aanwijzer en wetende dat we het originele veld extraheren.

De situatie met samengestelde index is vergelijkbaar (in plaats van op één element te bestellen, bestellen we op veel). U heeft bijvoorbeeld een verzameling:

{ "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

en wil een index { "item":1, "location":1, "stock":1 }. De opzoektabel ziet er als volgt uit (nog een keer - dit is niet een andere verzameling, dit is alleen voor demonstratie):

{ "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 }

Zie dat hier alles in principe is gesorteerd op item, dan op locatie en dan op pointer. Op dezelfde manier als bij een enkele index hoeven we niet alles te scannen. Als we een zoekopdracht hebben die zoekt naar item = 2, location = 5 and stock = 7 we kunnen snel identificeren waar documenten met item = 2 zijn en vervolgens op dezelfde manier snel identificeren waar tussen deze items item met location 5 enzovoort.

En nu een interessant deel . We hebben ook slechts één index gemaakt (hoewel dit een samengestelde index is, is het nog steeds één index) die we kunnen gebruiken om het element snel te vinden

  • alleen bij het item . Eigenlijk alles wat we hoeven te doen is slechts de eerste stap. Het heeft dus geen zin om nog een index {location :1} te maken omdat deze al wordt gedekt door een samengestelde index.
  • ook kunnen we snel alleen vinden op item and by location (we hebben slechts 2 stappen nodig).

Cool 1 index maar helpt ons op drie verschillende manieren. Maar wacht even:wat als we willen zoeken op item and stock . Oh, het lijkt erop dat we deze query ook kunnen versnellen. We kunnen in log(n) alle elementen met een specifiek item vinden en ... hier moeten we stoppen - magie is afgelopen. We moeten ze allemaal herhalen. Maar nog steeds redelijk goed.

Maar misschien kan het ons helpen met andere vragen. Laten we een zoekopdracht bekijken op location die eruit ziet alsof hij al is besteld. Maar als je ernaar kijkt, zie je dat dit een puinhoop is. Een in het begin en dan een op het einde. Het kan je helemaal niet helpen.

Ik hoop dat dit een paar dingen verduidelijkt:

  • waarom indexen goed zijn (verkort de tijd van O(n) naar potentieel O(log(n))
  • waarom samengestelde indexen kunnen helpen bij sommige zoekopdrachten, maar we hebben geen index gemaakt voor dat specifieke veld en helpen bij sommige andere zoekopdrachten.
  • welke indexen worden gedekt door samengestelde index
  • waarom indexen schadelijk kunnen zijn (het creëert een extra datastructuur die moet worden onderhouden)

En dit zou nog iets geldigs moeten vertellen:index is geen wondermiddel . Je kunt niet al je zoekopdrachten versnellen, dus het klinkt gek om te denken dat door indexen op alle velden te maken ALLES supersnel zou zijn.



  1. Hoe mongoDB te verbinden met de angular2-app?

  2. Een woordenboek in een lijst krijgen op sleutel in mongoDB (mongoengine)

  3. MongoDB update meerdere subdocumenten met of vraag

  4. Redis-transacties