Podano zwykłe standardowe zapytanie (bez limit()
lub sort()
lub cokolwiek wymyślnie zastosowanego), który ma warunek filtrowania na dwóch polach (jak w name
i age
w twoim przykładzie), aby znaleźć wynikowe dokumenty, MongoDB:
- wykonaj pełne skanowanie kolekcji (odczytaj każdy dokument w całej kolekcji, przeanalizuj BSON, znajdź odpowiednie wartości, przetestuj je z danymi wejściowymi i zwróć/odrzuć każdy dokument):To jest bardzo intensywne we/wy, a zatem powolne.
- użyj jednego indeksu które zawiera jedno z pól (użyj drzewa indeksów, aby zlokalizować odpowiedni podzbiór dokumentów, a następnie je zeskanuj):W zależności od dystrybucji danych/selektywności indeksowania może to być bardzo szybkie lub prawie nie przynosić żadnych korzyści (wyobraź sobie indeks na
age
w zbiorze danych milionów ludzi w wieku od 30 do 40 lat --> każde wyszukiwanie nadal dałoby nieskończoną liczbę dokumentów). - użyj dwóch indeksów które razem zawierają oba pola, o których mowa (załaduj oba indeksy, wykonaj wyszukiwanie kluczy, a następnie oblicz część wspólną wyników):Ponownie, w zależności od dystrybucji danych, może to zapewnić większą (lepszą) wydajność lub nie. Jednak w większości przypadków powinien być szybszy niż #2. Byłbym jednak zaskoczony, gdyby był naprawdę 10x wolniejszy niż #4 (jak wspomniałeś).
- użyj indeksu złożonego (dwa kolejne kluczowe wyszukiwania natychmiast prowadzą do wymaganych dokumentów):będzie to najszybsza opcja ze wszystkich, biorąc pod uwagę, że wymaga najmniej i najtańszych operacji, aby dostać się do właściwych dokumentów. Aby zapewnić jak największy poziom ponownego wykorzystania (nie wydajność, na którą to nie wpłynie) powinieneś ogólnie zacząć od najbardziej selektywnego pola, więc w twoim przypadku prawdopodobnie
name
a nieage
biorąc pod uwagę, że wiele osób będzie miało ten samage
(tak niska selektywność) w porównaniu doname
(wyższa selektywność). Ale ten wybór zależy również od konkretnego scenariusza i zapytań, które zamierzasz uruchomić w swojej bazie danych. W sieci jest całkiem niezły artykuł o tym, jak najlepiej zdefiniować indeks złożony, biorąc pod uwagę różne aspekty konkretnej sytuacji:https://emptysqua.re/blog/optimizing-mongodb-compound-indexes
Inne aspekty do rozważenia to:Aktualizacje indeksu mają określoną cenę. Jeśli jednak zależy Ci tylko na surowej prędkości odczytu i od czasu do czasu masz tylko kilka aktualizacji, powinieneś wybrać więcej/większe indeksy.
I ostatnia, ale nie mniej ważna (!) rada dotycząca nadmiernie używanych wyników:Profiluj swój system, używając prawdziwych danych, a być może nawet realistycznych scenariuszy obciążenia. A także kontynuuj pomiary w miarę zmian danych/systemu w czasie.
Dodatkowe lektury: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
Przecięcie indeksu a indeks złożony?
indeks złożony mongodb a przecięcie indeksu
Jakie znaczenie ma kolejność indeksów złożonych w MongoDB pod względem wydajności?
W MongoDB używam dużego zapytania, jak stworzę indeks złożony lub indeks pojedynczy, więc mój czas odpowiedzi przyspieszy