Aby rozwiązać problemy z powolnymi zapytaniami, użyj funkcji Query Explain, która umożliwia uzyskanie planu wykonywania zapytania i profilu wykonania w czasie działania. W sekcji poniżej znajdziesz czynności, które możesz wykonać, aby zoptymalizować wydajność zapytań w zależności od profilu wykonania:
Ograniczanie liczby wyników
Użyj pola zwróconych rekordów w drzewie wykonania, aby sprawdzić, czy zapytanie zwraca wiele dokumentów. Rozważ ograniczenie liczby zwracanych dokumentów za pomocą klauzuli $limit. Zmniejsza to rozmiar serializowanych bajtów wyników
zwracanych klientom przez sieć. Jeśli przed węzłem Limit występuje węzeł MajorSort, silnik zapytań może połączyć węzły Limit i MajorSort oraz zastąpić pełną materializację w pamięci i sortowanie sortowaniem TopN, co zmniejsza wymagania dotyczące pamięci dla zapytania.
Ograniczanie rozmiaru dokumentu wynikowego
Aby uniknąć pobierania niepotrzebnych pól, rozważ ograniczenie rozmiaru zwracanego dokumentu za pomocą klauzuli $project. Pomaga to zmniejszyć koszty obliczeniowe i koszty pamięci związane z przetwarzaniem wyników pośrednich oraz rozmiar serializowanych bajtów wyników zwracanych do klientów przez sieć. Jeśli wszystkie pola, do których odwołuje się zapytanie, są objęte zwykłym indeksem (nie wielokluczowym), umożliwia to również pełne pokrycie zapytania przez skanowanie indeksu, co pozwala uniknąć pobierania dokumentów z pamięci podstawowej.
Korzystanie z indeksów
Aby skonfigurować i zoptymalizować indeksy, wykonaj te czynności.
Sprawdź, czy zapytanie korzysta z indeksu.
Aby sprawdzić, czy zapytanie korzysta z indeksu, możesz sprawdzić węzły liści w drzewie wykonania. Jeśli węzeł liścia w drzewie wykonania to węzeł TableScan, oznacza to, że zapytanie nie korzysta z indeksu i skanuje dokumenty z pamięci podstawowej. Jeśli używany jest indeks, węzeł liścia drzewa wykonania będzie wyświetlać identyfikator indeksu i pola indeksu.
Sprawdź, czy użyty indeks można zoptymalizować.
Indeks jest przydatny w przypadku zapytania, jeśli może zmniejszyć liczbę dokumentów, które silnik zapytań musi pobrać z pamięci podstawowej, lub jeśli kolejność pól może spełnić wymagania zapytania dotyczące sortowania.
Jeśli zapytanie korzysta z indeksu, ale silnik zapytań nadal pobiera i odrzuca wiele dokumentów (co można stwierdzić na podstawie węzła skanowania, który zwraca wiele rekordów, a następnie węzła filtra, który zwraca niewiele rekordów), oznacza to, że predykat zapytania spełniony przy użyciu indeksu nie jest selektywny. Aby utworzyć bardziej odpowiedni indeks, przeczytaj artykuł Tworzenie indeksów.
Jeśli do zapytania jest używany indeks nieobejmujący wielu kluczy, ale silnik zapytań nadal wykonuje w pamięci ponowne sortowanie zbioru wyników, co jest wskazywane przez węzeł MajorSort w drzewie wykonania zapytania, oznacza to, że użyty indeks nie może być używany do spełnienia wymagania sortowania zapytania. Aby utworzyć bardziej odpowiedni indeks, zapoznaj się z następną sekcją.
Optymalizacja zapytań $lookup
Możesz zoptymalizować $lookup zapytania, dodając indeksy do from kolekcji, co pozwala operacji skutecznie znajdować pasujące dokumenty bez skanowania całej kolekcji.
$lookup z użytkownikami localField i foreignField
Jeśli w $lookup
etapie używasz opcji localField i foreignField, utwórz indeks w foreignField w kolekcji from.
$lookup z zagnieżdżonymi potokami
Jeśli na etapie $lookup używasz opcji pipeline z $match etapami, utwórz indeks w polach powiązanych z kolekcją zewnętrzną, aby uniknąć pełnego skanowania kolekcji:
- W przypadku etapów
$matchz semantyką filtra (np.{$match: {a: true}}) utwórz indeks w polach powiązanych z kolekcją zewnętrzną (a). - W przypadku etapów
$matchz semantyką agregacji, która porównuje pole ze stałą wartością (np.{$match: {$expr: {$gt: [a, 10]}}}) lub z porównaniami równości (eqlubin) między polami i zmiennymi zdefiniowanymi wlet(np.{$match: {$expr: {$eq: [a, "$$a"]}}}), utwórz indeks w polach w kolekcji zewnętrznej. Pamiętaj, że indeks wielokluczowy nie będzie używany w planowaniu.
Tworzenie indeksów
Postępuj zgodnie z dokumentacją dotyczącą zarządzania indeksami, aby tworzyć indeksy. Aby mieć pewność, że zapytanie może korzystać z indeksów, utwórz zwykłe indeksy (nie Multikey) z polami w tej kolejności:
- Wszystkie pola, które będą używane w operatorach równości. Aby zmaksymalizować szansę ponownego użycia w różnych zapytaniach, uporządkuj pola w kolejności malejącej liczby wystąpień pól w operatorach równości w zapytaniach.
- Wszystkie pola, według których będzie sortowana tabela (w tej samej kolejności).
- Pola, które będą używane w operatorach zakresu lub nierówności w kolejności malejącej selektywności ograniczeń zapytania.
- Pola, które będą zwracane w ramach zapytania w indeksie: uwzględnienie takich pól w indeksie umożliwia mu obsługę zapytania i uniknięcie pobierania dokumentu z pamięci podstawowej.
W przypadku zapytań, które obejmują filtrowanie i sortowanie pól tablicowych, rozważ utworzenie indeksów wielokluczowych.
Używanie wskazówki dotyczącej zapytania
Jeśli utworzysz bardziej odpowiedni indeks dla zapytania, ale silnik zapytań nie będzie go używać, możesz zastąpić preferencje silnika zapytań dotyczące indeksu, używając wskazówki dotyczącej zapytania.
Więcej informacji o wynikach zapytania wykonanego za pomocą funkcji Wyjaśnij zapytanie znajdziesz w artykule Informacje o wykonaniu zapytania.