Funkcja Wyjaśnienie zapytania umożliwia przesyłanie Cloud Firestore zapytań do
backendu i otrzymywanie szczegółowych statystyk wydajności wykonywania zapytań w backendzie. Działa podobnie jak operacja EXPLAIN [ANALYZE] w wielu relacyjnych systemach baz danych.
Żądania Wyjaśnienie zapytania można wysyłać za pomocą bibliotek klienta serwera Firestore.
Wyniki Wyjaśnienie zapytania pomagają zrozumieć, jak wykonywane są zapytania, wskazując nieefektywności i lokalizację prawdopodobnych wąskich gardeł po stronie serwera.
Wyjaśnienie zapytania:
- Dostarcza informacji o fazie planowania zapytania, dzięki czemu możesz dostosować indeksy zapytań i zwiększyć wydajność.
- Opcja analizy pomaga zrozumieć koszty i wydajność na podstawie poszczególnych zapytań oraz umożliwia szybkie iterowanie różnych wzorców zapytań w celu optymalizacji ich użycia.
Informacje o opcjach Wyjaśnienie zapytania: domyślna i analiza
Operacje Wyjaśnienie zapytania można wykonywać za pomocą opcji domyślna lub analiza.
W przypadku opcji domyślnej funkcja Wyjaśnienie zapytania planuje zapytanie, ale pomija etap wykonania. Spowoduje to zwrócenie informacji o etapie planowania. Możesz użyć tej opcji, aby sprawdzić, czy zapytanie ma niezbędne indeksy, i dowiedzieć się, które indeksy są używane. Pomoże Ci to na przykład sprawdzić, czy dane zapytanie używa indeksu złożonego, zamiast przecinać wiele różnych indeksów.
W przypadku opcji analizy funkcja Wyjaśnienie zapytania planuje i wykonuje zapytanie. Zwraca wszystkie wymienione wcześniej informacje o planowaniu wraz ze statystykami z czasu wykonywania zapytania. Będą one obejmować informacje o rozliczeniach zapytania oraz informacje o jego wykonaniu na poziomie systemu. Za pomocą tego narzędzia możesz testować różne konfiguracje zapytań i indeksów, aby zoptymalizować ich koszt i opóźnienie.
Ile kosztuje Wyjaśnienie zapytania?
Gdy używasz funkcji Wyjaśnienie zapytania z opcją domyślną, nie są wykonywane żadne operacje indeksowania ani odczytu. Niezależnie od złożoności zapytania naliczana jest opłata za 1 operację odczytu.
Gdy używasz funkcji Wyjaśnienie zapytania z opcją analizy, wykonywane są operacje indeksowania i odczytu, więc opłata za zapytanie jest naliczana jak zwykle. Za analizę nie są naliczane żadne dodatkowe opłaty – tylko zwykła opłata za wykonywane zapytanie.
Korzystanie z funkcji Wyjaśnienie zapytania z opcją domyślną
Aby przesłać żądanie z opcją domyślną, możesz użyć bibliotek klienta.
Pamiętaj, że żądania są uwierzytelniane za pomocą IAM, z użyciem tych samych uprawnień co w przypadku zwykłych operacji zapytań. Inne metody uwierzytelniania, takie jak Firebase Authentication, są ignorowane. Więcej informacji znajdziesz w przewodniku po IAM dla 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();
Node (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 wykonania. Zwrócone wyniki można przekonwertować na format 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.
Korzystanie z funkcji Wyjaśnienie zapytania z opcją analizy
Aby przesłać żądanie z opcją analizy, możesz użyć bibliotek klienta.
Pamiętaj, że żądania są uwierzytelniane za pomocą IAM, z użyciem tych samych uprawnień co w przypadku zwykłych operacji zapytań. Inne metody uwierzytelniania, takie jak Firebase Authentication, są ignorowane. Więcej informacji znajdziesz w przewodniku po IAM dla 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();
Node (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 obiektu planInfo.
Dokładny format odpowiedzi zależy od środowiska wykonania. 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 zmian
Przyjrzyjmy się przykładowemu scenariuszowi, w którym wysyłamy zapytanie o filmy według gatunku i kraju produkcji.
Dla ilustracji załóżmy, że mamy odpowiednik tego zapytania SQL.
SELECT * FROM /movies WHERE category = 'Romantic' AND country = 'USA';
Jeśli użyjemy opcji analizy, zwrócone dane pokażą, że zapytanie jest wykonywane na 2 indeksach z 1 polem: (category ASC, __name__ ASC) i (country ASC, __name__ ASC). Przeskanuje ono 16 500 wpisów indeksu, ale zwróci 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).
Ponowne uruchomienie zapytania z opcją analizy pokazuje, że dla tego zapytania został wybrany nowo utworzony indeks, a zapytanie jest wykonywane znacznie szybciej i wydajniej.
// 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", } } }