Poznawanie wydajności zapytań za pomocą funkcji Query Explain

Wyjaśnienie zapytania pozwala przesyłać zapytania Cloud Firestore do i otrzymywać szczegółowe statystyki wydajności wykonywania zapytań w backendzie w zamian. Działa jak operacja EXPLAIN [ANALYZE] w wielu w systemach relacyjnych baz danych.

Żądania zapytania Explain można wysyłać za pomocą bibliotek klienta serwera Firestore.

Wyniki funkcji Wyjaśnienie zapytania pomagają zrozumieć, jak zapytania są co pokazuje jego niewydajność i lokalizację prawdopodobnie po stronie serwera. które powodują wąskie gardła.

Wyjaśnienie zapytania:

  • Udostępnia informacje na temat fazy planowania zapytania, dzięki czemu możesz dostosować zapytanie tworzyć indeksy i zwiększać wydajność.
  • Korzystając z opcji analizy, możesz poznać koszty i skuteczność kampanii dla poszczególnych zapytań i umożliwia szybkie iteracje aby zoptymalizować korzystanie z nich.
.

Opcje wyjaśnienia zapytania: domyślne i analiza

Operacje Query Explain mogą być wykonywane za pomocą opcji default lub analyze (Analiza).

W przypadku opcji domyślnej zapytanie Explain planuje zapytanie, ale je pomija. na etapie realizacji. Spowoduje to zwrócenie informacji o etapie planera. Dostępne opcje Dzięki niemu możesz sprawdzić, czy zapytanie ma niezbędne indeksy, i dowiedzieć się, które . Pomoże Ci to na przykład sprawdzić, czy określony produkt w zapytaniu korzysta z indeksu złożonego zamiast nakładania się wielu różnych indeksów.

W przypadku opcji analizy zapytanie wyjaśnia zarówno plany, jak i wykonuje zapytania. Spowoduje to zwrot wszystkich wcześniej wymienionych informacji o planerze wraz z ze statystyk w środowisku wykonawczym wykonywania zapytań. Będą one obejmować płatności informacje o zapytaniu wraz ze statystykami na poziomie systemu dotyczącymi zapytania Za pomocą tego narzędzia możesz testować różne zapytania i indeksy pod kątem optymalizacji kosztów i czasu oczekiwania.

Ile kosztuje zapytanie Explain?

Gdy używasz metody Query Explain z opcją domyślną, brak operacji indeksowania ani odczytu . Niezależnie od złożoności zapytania naliczana jest jedna operacja odczytu.

Gdy używasz Query Explain z opcją analizy, operacji indeksowania i odczytu więc zapłacisz za nie jak zwykle. Nie ma żadnych dodatkowych za aktywność związaną z analizą, tylko zwykłą opłatę za zapytanie .

Użyj rozszerzenia Query Explain z opcją domyślną

Aby przesłać żądanie opcji domyślnej, możesz użyć bibliotek klienta.

Pamiętaj, że żądania są uwierzytelniane za pomocą uprawnień z użyciem tego samego do zwykłych operacji zapytań. innych technik uwierzytelniania, takich jak Uwierzytelnianie Firebase, są ignorowane. Więcej informacji znajdziesz w przewodniku na temat Uprawnienia bibliotek klienta serwera.

Java (administrator)

Query q = db.collection("col").whereGreaterThan("a", 1);
ExplainOptions options = ExplainOptions.builder().build();

ExplainResults<QuerySnapshot> explainResults = q.explain(options).get();
ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();

    
Węzeł (administrator)

const q = db.collection('col').where('country', '=', 'USA');
const options = { analyze : 'false' };

const explainResults = await q.explain(options);

const metrics = explainResults.metrics;
const plan = metrics.planSummary;

    

Dokładny format odpowiedzi zależy od środowiska wykonawczego. Zwrócone wyniki można przekonwertować do formatu JSON. Przykład:

{
    "indexes_used": [
        {"query_scope": "Collection", "properties": "(category ASC, __name__ ASC)"},
        {"query_scope": "Collection", "properties": "(country ASC, __name__ ASC)"},
    ]
}

Więcej informacji znajdziesz w dokumentacji raportu Wyjaśnienie zapytania.

Użyj rozszerzenia Query Explain z opcją analizy

Aby przesłać żądanie opcji analizy, możesz użyć bibliotek klienta.

Pamiętaj, że żądania są uwierzytelniane za pomocą uprawnień z użyciem tego samego do zwykłych operacji zapytań. innych technik uwierzytelniania, takich jak Uwierzytelnianie Firebase, są ignorowane. Więcej informacji znajdziesz w przewodniku na temat Uprawnienia bibliotek klienta serwera.

Java (administrator)

Query q = db.collection("col").whereGreaterThan("a", 1);

ExplainOptions options = ExplainOptions.builder().setAnalyze(true).build();

ExplainResults<QuerySnapshot> explainResults = q.explain(options).get();

ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();
List<Map<String, Object>> indexesUsed = planSummary.getIndexesUsed();
ExecutionStats stats = metrics.getExecutionStats();

    
Węzeł (administrator)

const q = db.collection('col').where('country', '=', 'USA');

const options = { analyze : 'true' };

const explainResults = await q.explain(options);

const metrics = explainResults.metrics;
const plan = metrics.planSummary;
const indexesUsed = plan.indexesUsed;
const stats = metrics.executionStats;

    

Poniższy przykład pokazuje obiekt stats zwrócony oprócz planInfo. Dokładny format odpowiedzi zależy od środowiska wykonawczego. przykładowa odpowiedź jest w formacie JSON.

{
    "resultsReturned": "5",
    "executionDuration": "0.100718s",
    "readOperations": "5",
    "debugStats": {
               "index_entries_scanned": "95000",
               "documents_scanned": "5"
               "billing_details": {
                     "documents_billable": "5",
                     "index_entries_billable": "0",
                     "small_ops": "0",
                     "min_query_cost": "0",
               }
    }

}

Więcej informacji znajdziesz w dokumentacji raportu Wyjaśnienie zapytania.

Interpretowanie wyników i wprowadzanie korekt

Spójrzmy na przykładowy scenariusz, w którym wyszukujemy filmy według gatunku, kraj produkcji.

Na potrzeby ilustracji załóżmy, że jest to odpowiednik tego zapytania SQL.

SELECT *
FROM /movies
WHERE category = 'Romantic' AND country = 'USA';

Jeśli użyjemy opcji analizy, zwracane dane pokazują zapytanie działa na 2 indeksach z pojedynczym polem: (category ASC, __name__ ASC) i (country ASC, __name__ ASC) Skanuje 16 500 wpisów indeksu, ale zwraca tylko 1200 dokumentów.

// Output query planning info
{
    "indexes_used": [
        {"query_scope": "Collection", "properties": "(category ASC, __name__ ASC)"},
        {"query_scope": "Collection", "properties": "(country ASC, __name__ ASC)"},
    ]
}

// Output query status
{
    "resultsReturned": "1200",
    "executionDuration": "0.118882s",
    "readOperations": "1200",
    "debugStats": {
               "index_entries_scanned": "16500",
               "documents_scanned": "1200"
               "billing_details": {
                     "documents_billable": "1200",
                     "index_entries_billable": "0",
                     "small_ops": "0",
                     "min_query_cost": "0",
               }
    }
}

Aby zoptymalizować wydajność wykonywania zapytania, możesz utworzyć w pełni pokryty indeks złożony (category ASC, country ASC, __name__ ASC).

Uruchamiając zapytanie ponownie z opcją analizy, zobaczymy, że dla tego zapytania zostanie wybrany nowo utworzony indeks, przez co zapytanie będzie działać znacznie szybciej i efektywniej.

// Output query planning info
{
    "indexes_used": [
        {"query_scope": "Collection", "properties": "(category ASC, country ASC,  __name__ ASC)"}
    ]
}

// Output query stats
{
    "resultsReturned": "1200",
    "executionDuration": "0.026139s",
    "readOperations": "1200",
    "debugStats": {
               "index_entries_scanned": "1200",
               "documents_scanned": "1200"
               "billing_details": {
                     "documents_billable": "1200",
                     "index_entries_billable": "0",
                     "small_ops": "0",
                     "min_query_cost": "0",
               }
    }
}