sql >> Databáze >  >> NoSQL >> MongoDB

MongoDb:jak vytvořit správný (složený) index pro data s mnoha prohledávatelnými poli

Pokusím se vysvětlit, co to znamená na příkladu. Indexy založené na B-stromu nejsou něco specifického pro mongodb. Na rozdíl od toho je to docela běžný koncept.

Takže když vytvoříte index - ukážete databázi jednodušší způsob, jak něco najít. Ale tento index je někde uložen s ukazatelem ukazujícím na umístění původního dokumentu. Tato informace je uspořádaná a můžete se na ni dívat jako na binární strom, který má opravdu pěknou vlastnost:vyhledávání je redukováno z O(n) (lineární skenování) na O(log(n)) . Což je mnohem rychlejší, protože pokaždé, když zkrátíme náš prostor na polovinu (potenciálně můžeme snížit čas z 10^6 na 20 vyhledávání). Například máme velkou sbírku s polem {a : some int, b: 'some other things'} a pokud jej indexujeme podle a, skončíme s další datovou strukturou, která je řazena podle a . Vypadá to takto (tím nechci říct, že jde o jinou kolekci, to je jen pro ukázku):

{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

Takže právě teď hledáme pole a =18. Místo toho, abychom procházeli jeden po druhém všechny prvky, vezmeme něco uprostřed a pokud je to větší než 18, tak spodní část rozdělíme napůl a tam prvek zkontrolujeme . Pokračujeme, dokud nenajdeme a =18. Pak se podíváme na ukazatel a když to víme, extrahujeme původní pole.

Situace se složeným indexem je podobná (místo řazení podle jednoho prvku seřazujeme podle mnoha). Máte například sbírku:

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

a chcete index { "položka":1, "umístění":1, "akcie":1}. Vyhledávací tabulka by vypadala takto (ještě jednou – toto není další kolekce, toto je jen pro ukázku):

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

Podívejte se, že zde je vše v podstatě seřazeno podle položky, pak podle umístění a poté podle ukazatele. Stejně jako u jednoho indexu nemusíme skenovat vše. Pokud máme dotaz, který hledá item = 2, location = 5 and stock = 7 můžeme rychle identifikovat, kde jsou dokumenty s item = 2 jsou a pak stejným způsobem rychle identifikujte, kde mezi těmito položkami je položka s location 5 a tak dále.

A právě teď zajímavá část . Také jsme vytvořili pouze jeden index (ačkoli se jedná o složený index, stále je to jeden index), můžeme jej použít k rychlému nalezení prvku

  • pouze pomocí item . Opravdu vše, co musíme udělat, je jen první krok. Nemá tedy smysl vytvářet další index {umístění:1}, protože je již pokryt složeným indexem.
  • také můžeme rychle najít pouze podle item and by location (potřebujeme pouze 2 kroky).

Cool 1 index, ale pomáhá nám třemi různými způsoby. Ale počkejte chvíli:co když chceme hledat podle item and stock . Vypadá to, že můžeme tento dotaz také urychlit. Můžeme v log(n) najít všechny prvky s konkrétním předmětem a ... zde musíme zastavit - magie skončila. Musíme je projít všemi. Ale pořád docela dobrý.

Ale snad nám to pomůže s dalšími dotazy. Podívejme se na dotaz podle location který vypadá, že už byl objednán. Ale když se na to podíváte - vidíte, že je to nepořádek. Jeden na začátku a pak jeden na konci. To vám vůbec nemůže pomoci.

Doufám, že to objasní několik věcí:

  • proč jsou indexy dobré (zkrátit čas z O(n) na potenciálně O(log(n))
  • proč mohou složené indexy pomoci s některými dotazy, přesto jsme pro toto konkrétní pole nevytvořili index a pomáhají s některými dalšími dotazy.
  • jaké indexy jsou pokryty složeným indexem
  • proč mohou indexy škodit (vytváří další datovou strukturu, která by měla být udržována)

A to by mělo vypovídat o další platné věci:index není stříbrná kulka . Nemůžete urychlit všechny své dotazy, takže zní hloupě si myslet, že vytvořením indexů na všech polích by VŠECHNO bylo super rychlé.



  1. MongoDB Query, najít vše podle ID uživatele

  2. Aktualizace konkrétního prvku v poli pomocí MongoDB / Meteor

  3. mongodb unwated odstranění prázdného pole při aktualizaci

  4. nelze se připojit k mongodb hostovanému na vzdáleném serveru pomocí monk