Optymalizowanie wydajności zapytań

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 wykonywania:

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ą etapu 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, używając select(...), aby zwracać tylko wymagane pola, lub remove_fields(...), aby odrzucać zbyt duże pola. Pomaga to zmniejszyć koszty obliczeniowe i pamięciowe przetwarzania wyników pośrednich oraz rozmiar zserializowanych bajtów wyników zwracanych klientom przez sieć. W przypadkach, gdy wszystkie pola, do których odwołuje się zapytanie, są objęte zwykłym indeksem, umożliwia to również pełne objęcie zapytania skanowaniem indeksu, co eliminuje konieczność 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 wykonywania 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.

Identyfikowanie lepszego indeksu

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 indeks jest używany w zapytaniu, ale mechanizm zapytań nadal pobiera i odrzuca wiele dokumentów, co jest identyfikowane przez węzeł skanowania, który zwraca wiele rekordów, a następnie 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 indeks jest używany w zapytaniu, ale mechanizm zapytań nadal wykonuje zmianę kolejności 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ą.

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:

  1. 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.
  2. Wszystkie pola, według których będzie przeprowadzane sortowanie (w tej samej kolejności).
  3. Pola, które będą używane w operatorach zakresu lub nierówności, w kolejności malejącej selektywności ograniczeń zapytania.
  4. Pola, które zostaną zwrócone w ramach zapytania w indeksie: uwzględnienie takich pól w indeksie pozwala mu objąć zapytanie i uniknąć konieczności pobierania dokumentu z pamięci głównej.

Wymuszanie skanowania indeksu lub tabeli

Gdy wysyłasz zapytanie do Cloud Firestore, automatycznie używa on indeksów, które mogą zwiększyć wydajność zapytania. Dzięki temu nie musisz określać indeksu dla zapytań. W przypadku zapytań, które mają kluczowe znaczenie dla Twojego zbioru zadań, zalecamy jednak użycie opcji forceIndex, aby uzyskać bardziej spójną wydajność.

W niektórych przypadkach Cloud Firestore może wybrać indeks, który zwiększa czas oczekiwania na zapytanie. Jeśli po wykonaniu czynności opisanych w sekcji dotyczącej rozwiązywania problemów ze spadkiem wydajności uznasz, że warto wypróbować inny indeks dla zapytania, możesz określić indeks za pomocą opcji forceIndex.

Możesz użyć opcji forceIndex na dowolnym etapie wejściowym w operacjach potoku, aby zastąpić domyślny plan zapytania Cloud Firestore i określić indeks do użycia lub wymusić skanowanie tabeli.

Wymuszanie określonego indeksu

Aby wymusić użycie określonego indeksu przez zapytanie, podaj identyfikator indeksu jako ciąg znaków w opcji forceIndex. Identyfikator indeksu znajdziesz w konsoli lub w komunikatach o błędach.

Poniższy przykład wymusza na planiście użycie indeksu o identyfikatorze CICAgOi36pgK:

Node.js
// Force Planner to use Index ID CICAgOi36pgK
await db.pipeline()
  .collectionGroup({ collectionId: "customers", forceIndex: "CICAgOi36pgK" })
  .limit(100)
  .execute();
Java
// Force Planner to use Index ID CICAgOi36pgK
Pipeline.Snapshot results1 =
    firestore.pipeline()
      .collectionGroup("customers", new CollectionGroupOptions()
          .withHints(new CollectionHints().withForceIndex("CICAgOi36pgK")))
      .limit(100)
      .execute().get();
Go
// Force Planner to use Index ID CICAgOi36pgK
snapshot1 := client.Pipeline().
	CollectionGroup("customers", firestore.WithForceIndex("CICAgOi36pgK")).
	Limit(100).
	Execute(ctx)

Oto kilka przypadków użycia, w których warto wymusić użycie konkretnego indeksu:

  • testowanie wydajności różnych indeksów;
  • zapewnienie, że w zapytaniu zostanie użyty konkretny, znany jako optymalny indeks;
  • zastępowanie optymalizatora, gdy jego domyślny wybór jest nieoptymalny w przypadku konkretnego zapytania;

Jeśli nie znajdzie określonego indeksu, zapytanie się nie powiedzie.

Wymuszanie skanowania tabeli

Skanowanie tabeli odczytuje dokumenty w kolekcji lub grupie kolekcji bez użycia indeksów pomocniczych. Aby wymusić skanowanie tabeli, ustaw forceIndex na primary.

Poniższy przykład wymusza skanowanie tabeli:

// Force Planner to only do a Full-Table Scan
db.pipeline()
  .collectionGroup({ collectionId: "customers", forceIndex: "primary" })
  .limit(100)

Skanowanie tabeli może być przydatne w tych przypadkach:

  • bardzo małych kolekcji, w przypadku których narzut indeksu nie jest uzasadniony;
  • W przypadku zapytań, które uzyskują dostęp do większości dokumentów w kolekcji.
  • Do debugowania i porównywania wydajności.

Korzystanie z forceIndex z wyjaśnieniem zapytania

Możesz użyć wyjaśnienia zapytania w trybie explain lub analyze, aby obserwować efekty działania forceIndex:

  • Sprawdź, czy usługa Cloud Firestore użyła określonego indeksu w forceIndex, sprawdzając węzły liści drzewa wykonania pod kątem identyfikatora indeksu.
  • Sprawdź, czy podczas korzystania z forceIndex: "primary" w planie pojawia się węzeł TableScan.
  • W trybie analyze porównaj wskaźniki skuteczności, takie jak czas oczekiwania, zeskanowane dokumenty i zeskanowane wpisy indeksu, z użyciem forceIndex i bez niego, aby dostosować wydajność zapytań.

forceIndex – sprawdzone metody

Chociaż forceIndex zapewnia większą kontrolę nad wykonywaniem zapytań, optymalizator zapytań Cloud Firestore jest ogólnie skuteczny w większości przypadków użycia. Podczas korzystania z atrybutu forceIndex weź pod uwagę te sprawdzone metody:

  • Używaj forceIndex z rozwagą. Jeśli zauważysz nieoptymalną wydajność domyślnego planu zapytania, przed wymuszeniem indeksu użyj funkcji Query Explain, aby zdiagnozować problem.
  • Gdy używasz forceIndex, przetestuj zapytania z realistycznymi ilościami danych, aby poznać ich charakterystykę pod względem wydajności i kosztów.
  • Unikaj używania forceIndex: "primary" w dużych kolekcjach w środowiskach produkcyjnych.

Więcej informacji o danych wyjściowych zapytania wykonanego za pomocą funkcji wyjaśniania zapytań znajdziesz w artykule Informacje o wykonywaniu zapytań.