Дадена е обикновена стандартна заявка (без limit()
или sort()
или нещо фантастично приложено), което има условие за филтриране на две полета (както в name
и age
във вашия пример), за да намери получените документи, MongoDB ще:
- направете пълносканиране на колекция (прочетете всеки документ в цялата колекция, анализирайте BSON, намерете въпросните стойности, тествайте ги спрямо входа и върнете/изхвърлете всеки документ):Това е супер интензивно I/O и следователно бавно.
- използвайте един индекс който съдържа едно от полетата (използвайте дървото на индексите, за да намерите подходяща подмножества от документи, последвано от сканиране от тях):В зависимост от вашето разпространение на данни/селективност на индекса това може да бъде много бързо или почти не предоставя никаква полза (представете си индекс на
age
в набор от данни от милиони хора между 30 и 40 години --> всяко търсене все пак ще доведе до безкраен брой документи). - използвайте два индекса които заедно съдържат и двете въпросни полета (заредете двата индекса, извършете ключови търсения, след което изчислите пресечната точка на резултатите):Отново, в зависимост от вашето разпределение на данните, това може или не може да ви даде голяма(по-голяма) производителност. В повечето случаи обаче трябва да е по-бързо от #2. Бих се изненадал обаче, ако наистина беше 10 пъти по-бавно от #4 (както споменахте).
- използвайте съставен индекс (две последващи ключови търсения веднага водят до необходимите документи):Това ще бъде най-бързият вариант от всички, като се има предвид, че изисква най-малко и най-евтини операции, за да стигнете до правилните документи. За да осигурите най-високо ниво на повторна употреба (а не производителност, която няма да бъде засегната от това), като цяло трябва първо да започнете с най-селективното поле, така че във вашия случай вероятно
name
а неage
като се има предвид, че много хора ще имат една и същаage
(толкова ниска селективност) в сравнение сname
(по-висока селективност). Но този избор зависи и от вашия конкретен сценарий и от заявките, които възнамерявате да изпълнявате към вашата база данни. В мрежата има доста добра статия за това как най-добре да дефинирате съставен индекс, като се вземат предвид различни аспекти на вашата конкретна ситуация:https://emptysqua.re/blog/optimizing-mongodb-compound-indexes
Други аспекти, които трябва да се вземат предвид, са:Актуализациите на индекса идват на определена цена. Въпреки това, ако всичко, което ви интересува, е скоростта на четене в суров вид и имате само няколко актуализации от време на време, тогава трябва да търсите повече/по-големи индекси.
И не на последно място (!) Прекомерно използвания съвет за крайния резултат:Профилирайте по дяволите вашата система, използвайки реални данни и може би дори реалистични сценарии за натоварване. И също така продължете да измервате, тъй като вашите данни/система се променят с течение на времето.
Допълнителни показания:https://docs.mongodb.com/manual/core/query-optimization/index.html
https://dba.stackexchange.com/questions/158240/mongodb-index-intersection-does-not-eliminate-the-need-for-creating-compound-in
Индексно пресичане спрямо съставен индекс?
mongodb compund индекс срещу пресичане на индекс
Какво значение има редът на съставните индекси в MongoDB по отношение на производителността?
В MongoDB използвам голяма заявка, как ще създам съставен индекс или единичен индекс, така че времето ми за отговор се увеличава