Aby rozwiązać problemy z powolnymi zapytaniami, użyj funkcji Query Explain, aby uzyskać plan wykonywania zapytania i profil wykonywania w czasie działania. W sekcji poniżej opisano czynności, które możesz wykonać, aby zoptymalizować wydajność zapytania 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 zserializowanych bajtów wyników zwracanych klientom przez sieć. W przypadkach, gdy węzeł Limit jest poprzedzony węzłem MajorSort, mechanizm zapytań może połączyć węzły Limit i MajorSort oraz zastąpić pełną materializację i sortowanie w pamięci sortowaniem TopN, co zmniejsza zapotrzebowanie zapytania na pamięć.
Ograniczanie rozmiaru dokumentu wynikowego
Rozważ ograniczenie rozmiaru zwracanego dokumentu za pomocą klauzuli $project, aby uniknąć pobierania niepotrzebnych pól. Pomaga to zmniejszyć koszty obliczeniowe i pamięciowe przetwarzania wyników pośrednich oraz rozmiar bajtów zserializowanych wyników zwracanych klientom przez sieć. W przypadkach, gdy wszystkie pola, do których odwołuje się zapytanie, są objęte zwykłym indeksem (nie wielokluczowym), umożliwia to również pełne objęcie zapytania skanowaniem indeksu, co pozwala uniknąć konieczności pobierania dokumentów z pamięci głównej.
Używanie indeksów
Aby skonfigurować i zoptymalizować indeksy, postępuj zgodnie z poniższymi instrukcjami.
Sprawdzanie, czy zapytanie używa indeksu
Możesz sprawdzić, czy zapytanie używa indeksu, sprawdzając węzły liści w drzewie wykonywania. Jeśli węzeł liścia drzewa wykonania jest węzłem TableScan, oznacza to, że zapytanie nie używa indeksu i skanuje dokumenty z pamięci podstawowej. Jeśli używany jest indeks, węzeł liścia drzewa wykonania wyświetli identyfikator indeksu i pola indeksu.
Sprawdź, czy używany indeks można zoptymalizować.
Indeks jest przydatny w przypadku zapytania, jeśli może zmniejszyć liczbę dokumentów, które mechanizm zapytań musi pobrać z pamięci podstawowej, lub jeśli kolejność pól może spełnić wymagania dotyczące sortowania zapytania.
Jeśli do zapytania jest używany indeks, ale mechanizm zapytań nadal pobiera i odrzuca wiele dokumentów, co można rozpoznać po węźle skanowania, który zwraca wiele rekordów, a po nim następuje węzeł 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, zapoznaj się z artykułem Tworzenie indeksów.
Jeśli w zapytaniu używany jest indeks inny niż wielokluczowy, ale silnik zapytań nadal wykonuje ponowne porządkowanie zbioru wyników w pamięci, co jest identyfikowane przez węzeł MajorSort w drzewie wykonywania zapytania, oznacza to, że użytego indeksu nie można użyć do spełnienia wymagania sortowania zapytania. Aby utworzyć bardziej odpowiedni indeks, zapoznaj się z następną sekcją.
Optymalizuję zapytania ($lookup)
Możesz zoptymalizować zapytania $lookup, dodając indeksy do kolekcji from, co pozwoli na wydajne znajdowanie pasujących dokumentów bez skanowania całej kolekcji.
$lookup z localField i foreignField
Jeśli używasz opcji localField i foreignField na etapie $lookup, utwórz indeks dla foreignField w kolekcji from.
$lookup z zagnieżdżonymi potokami
Jeśli używasz opcji pipeline na etapie $lookup z etapami $match, utwórz indeks na polach zaangażowanych w kolekcję zewnętrzną, aby uniknąć pełnego skanowania kolekcji:
- W przypadku etapów
$matchz semantyką filtra (np.{$match: {a: true}}) utwórz indeks pól, których dotyczy problem, w kolekcji zewnętrznej (a). - W przypadku etapów
$matchz semantyką agregacji, która porównuje pole z wartością stałą (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 pól w kolekcji zewnętrznej. Pamiętaj, że indeks wielokluczowy nie będzie używany w planowaniu.
Tworzenie indeksów
Aby utworzyć indeksy, postępuj zgodnie z dokumentacją dotyczącą zarządzania indeksami. Aby mieć pewność, że zapytanie może używać indeksów, utwórz zwykłe indeksy (nie wielokluczowe) z polami w tej kolejności:
- Wszystkie pola, które będą używane w operatorach równości. Aby zmaksymalizować szansę na ponowne użycie w zapytaniach, uporządkuj pola w kolejności malejącej według występowania pól w operatorach równości w zapytaniach.
- Wszystkie pola, według których będzie przeprowadzane sortowanie (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 zostaną zwrócone jako część zapytania w indeksie: uwzględnienie takich pól w indeksie pozwala indeksowi objąć zapytanie i uniknąć konieczności pobierania dokumentu z pamięci głównej.
W przypadku zapytań, które obejmują filtrowanie i sortowanie pól tablic, rozważ utworzenie indeksów wielokluczowych.
Użyj wskazówki dotyczącej zapytania
Jeśli masz utworzony bardziej odpowiedni indeks dla zapytania, ale silnik zapytań go nie używa, możesz zastąpić preferencje indeksu silnika zapytań, używając wskazówki dotyczącej zapytania.
Więcej informacji o danych wyjściowych zapytania wykonanego za pomocą funkcji wyjaśniania zapytań znajdziesz w artykule Informacje o wykonywaniu zapytań.