MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Индекс на тройните съединения на Монго

долен ред / tl;dr: Индекс b може да бъде „пропуснат“, ако a и c са запитани за равенство или неравенство, но не, например, за сортиране на c .

Това е много добър въпрос. За съжаление не можах да намеря нищо, което да отговаря авторитетно на това по-подробно. Вярвам, че ефективността на подобни заявки се е подобрила през последните години, така че не бих се доверил на стар материал по темата.

Цялото нещо е доста сложно, защото зависи от селективността на вашите индекси и от това дали заявите за равенство, неравенство и/или сортиране, така че explain() е единственият ти приятел, но ето някои неща, които открих:

Предупреждение :Това, което идва сега, е смесица от експериментални резултати, разсъждения и догадки. Може да разтягам аналогията на Кайл твърде далеч и може и да греша напълно (и лош късмет, защото резултатите от теста ми слабо съвпадат с разсъжденията ми).

Ясно е, че може да се използва индексът на А, който в зависимост от селективността на А със сигурност е много полезен. „Пропускането“ B може да бъде сложно или не. Нека запазим това подобно на примера с готварска книга на Кайл:

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

Ако сега ме помолите да намеря френско ястие, наречено "Chateaubriand", мога да използвам индекс A и тъй като не знам съставката, ще трябва да сканирам всички ястия в A . От друга страна знам, че списъкът с ястия във всяка категория е сортиран чрез индекса C , така че ще трябва само да търся низовете, започващи с, да речем, "Ча" във всеки списък с съставки. Ако има 50 съставки, ще ми трябват 50 прегледа вместо само една, но това е много по-добре, отколкото да се налага да сканирам всяко френско ястие!

В моите експерименти броят беше много по-малък от броя на отделните стойности в b :никога не изглеждаше да надвишава 2. Тествах обаче това само с една колекция и вероятно е свързано със селективността на b -индекс.

Ако ме помолите да ви дам списък по азбучен ред на всички френски ястия , обаче щях да имам проблема . Сега индексът на C е безполезен, ще трябва да слея и сортирам всички тези индексни списъци. Ще трябва да сканирам всеки елемент, за да го направя.

Това се отразява в моите тестове. Ето някои опростени резултати. Оригиналната колекция има дати, ints и низове, но исках да запазя нещата прости, така че вече е всичко ints.

По същество има само два класа заявки:тези, при които nscanned <=2 * limit , и тези, които трябва да сканират цялата колекция (120k документи). Индексът е {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 }});

Вашият пробег ще варира.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB 3 Java проверява дали съществува колекция

  2. MongoDB регистрира всички заявки

  3. Как мога да обещая собствения Javascript драйвер на MongoDB, използвайки bluebird?

  4. Как да използвате моделиране на данни MongoDB за подобряване на операциите с пропускателна способност

  5. MongoDB $lte оператор на конвейера за агрегация