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

Mongo Triple Compound Index

sečteno a podtrženo / tl;dr: Index b lze 'přeskočit', pokud a a c jsou dotazovány na rovnost nebo nerovnost, ale ne například na řazení na c .

To je velmi dobrá otázka. Bohužel jsem nenašel nic, co by na to autoritativně odpovídalo podrobněji. Věřím, že výkon těchto dotazů se za poslední roky zlepšil, takže bych nevěřil starému materiálu na toto téma.

Celá věc je poměrně komplikovaná, protože závisí na selektivitě vašich indexů a na tom, zda dotazujete na rovnost, nerovnost a/nebo řazení, takže explain() je tvůj jediný přítel, ale našel jsem několik věcí:

Upozornění :Co nyní přichází, je směs experimentálních výsledků, uvažování a hádání. Možná zavádím Kyleovu analogii příliš daleko a mohu se dokonce úplně mýlit (a smůla, protože výsledky mých testů volně odpovídají mým úvahám).

Je jasné, že lze použít index A, což je v závislosti na selektivitě A jistě velmi užitečné. „Přeskočit“ B může být složité, ale také ne. Nechme to podobné jako v příkladu Kyleovy kuchařky:

French
    Beef
        ...
    Chicken
        Coq au Vin
        Roasted Chicken
    Lamb
        ...
    ...

Pokud mě nyní požádáte, abych našel nějaké francouzské jídlo s názvem "Chateaubriand", mohu použít index A a protože neznám přísadu, budu muset naskenovat všechna jídla v A . Na druhou stranu vím, že seznam jídel v každé kategorii je řazen podle indexu C , takže budu muset hledat pouze řetězce začínající, řekněme, "Cha" v každém seznamu přísad. Pokud bude 50 ingrediencí, budu potřebovat 50 vyhledávání místo jednoho, ale to je mnohem lepší, než muset skenovat každé francouzské jídlo!

V mých experimentech bylo číslo mnohem menší než počet různých hodnot v b :nezdálo se, že by to nikdy přesáhlo 2. Testoval jsem to však pouze s jedinou kolekcí a pravděpodobně to souvisí se selektivitou b -index.

Pokud jste mě požádali, abych vám dal abecedně seřazený seznam všech francouzských jídel , i když bych měl problém . Nyní index na C je bezcenné, musel bych všechny ty seznamy indexů sloučit a třídit. Abych to udělal, budu muset naskenovat každý prvek.

To se odráží v mých testech. Zde jsou některé zjednodušené výsledky. Původní sbírka obsahuje data-časy, ints a řetězce, ale chtěl jsem, aby to bylo jednoduché, takže je to teď všechno ints.

V podstatě existují pouze dvě třídy dotazů:ty, kde je nscanned <=2 * limit a ty, které musí naskenovat celou sbírku (120 tisíc dokumentů). Index je {a, b, c} :

// fast (range query on c while skipping b)
> db.Test.find({"a" : 43, "c" : { $lte : 45454 }});
// slow (sorting)
> db.Test.find({"a" : 43, "c" : { $lte : 45454 }}).sort({ "c" : -1});
> db.Test.find({"a" : 43, "c" : { $lte : 45454 }}).sort({ "b" : -1}); 

// fast (can sort on c if b included in the query)
> db.Test.find({"a" : 43, "b" : 7887, "c" : { $lte : 45454 }}).sort({ "c" : -1});

// fast (older tutorials claim this is slow)
> db.Test.find({"a" : {$gte : 43}, "c" : { $lte : 45454 }});

Váš počet najetých kilometrů se bude lišit.



  1. Může Redis zapisovat do databáze, jako je PostgreSQL?

  2. Hadoop Combiner Úvod, funkce a výhody

  3. Jak získat hodnoty z Redis pomocí klíčů, které obsahují mezery?

  4. MongoDB se nerovná