Query Explain vous permet d'envoyer des requêtes Cloud Firestore au
backend et de recevoir en retour des statistiques détaillées sur les performances de l'exécution des requêtes backend. Elle fonctionne comme l'opération EXPLAIN [ANALYZE] dans de nombreux systèmes de bases de données relationnelles.
Les requêtes Query Explain peuvent être envoyées à l'aide des bibliothèques clientes du serveur Firestore.
Les résultats de Query Explain vous aident à comprendre comment vos requêtes sont exécutées, en vous montrant les inefficacités et l'emplacement des goulots d'étranglement probables côté serveur.
Query Explain:
- Fournit des insights sur la phase de planification des requêtes afin que vous puissiez ajuster vos index de requêtes et améliorer l'efficacité.
- À l'aide de l'option d'analyse, vous aide à comprendre vos coûts et vos performances par requête, et vous permet d'itérer rapidement sur différents modèles de requêtes afin d'optimiser leur utilisation.
Comprendre les options de Query Explain : par défaut et analyse
Les opérations Query Explain peuvent être effectuées à l'aide de l'option par défaut ou de l'option analyse.
Avec l'option par défaut, Query Explain planifie la requête, mais ignore l'étape d'exécution. Les informations sur l'étape de planification sont renvoyées. Vous pouvez les utiliser pour vérifier qu'une requête dispose des index nécessaires et comprendre quels index sont utilisés. Cela vous aidera, par exemple, à vérifier qu'une requête particulière utilise un index composite plutôt que d'avoir à croiser de nombreux index différents.
Avec l'option d'analyse, Query Explain planifie et exécute la requête. Toutes les informations de planification mentionnées précédemment sont renvoyées, ainsi que les statistiques du temps d'exécution de la requête. Cela inclut les informations de facturation de la requête, ainsi que des insights au niveau du système sur l'exécution de la requête. Vous pouvez utiliser cet outil pour tester différentes configurations de requêtes et d'index afin d'optimiser leur coût et leur latence.
Quel est le coût de Query Explain ?
Lorsque vous utilisez Query Explain avec l'option par défaut, aucune opération d'indexation ni de lecture n'est effectuée. Quelle que soit la complexité de la requête, une opération de lecture est facturée.
Lorsque vous utilisez Query Explain avec l'option d'analyse, des opérations d'indexation et de lecture sont effectuées. Vous êtes donc facturé pour la requête comme d'habitude. L'activité d'analyse n'entraîne aucun frais supplémentaire, mais uniquement les frais habituels pour l'exécution de la requête.
Utiliser Query Explain avec l'option par défaut
Vous pouvez utiliser les bibliothèques clientes pour envoyer une requête d'option par défaut.
Notez que les requêtes sont authentifiées avec IAM, en utilisant les mêmes autorisations que pour les opérations de requête standards. Les autres techniques d'authentification, comme Firebase Authentication, sont ignorées. Pour en savoir plus, consultez le guide sur IAM pour les bibliothèques clientes du serveur.
Java (administrateur)
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 (administrateur)
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;
Le format exact de la réponse dépend de l'environnement d'exécution. Les résultats renvoyés peuvent être convertis au format JSON. Exemple :
{
"indexes_used": [
{"query_scope": "Collection", "properties": "(category ASC, __name__ ASC)"},
{"query_scope": "Collection", "properties": "(country ASC, __name__ ASC)"},
]
}Pour en savoir plus, consultez la documentation de référence sur le rapport Query Explain.
Utiliser Query Explain avec l'option d'analyse
Vous pouvez utiliser les bibliothèques clientes pour envoyer une requête d'option d'analyse.
Notez que les requêtes sont authentifiées avec IAM, en utilisant les mêmes autorisations que pour les opérations de requête standards. Les autres techniques d'authentification, comme Firebase Authentication, sont ignorées. Pour en savoir plus, consultez le guide sur IAM pour les bibliothèques clientes du serveur.
Java (administrateur)
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 (administrateur)
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;
L'exemple suivant montre l'objet stats renvoyé en plus de planInfo.
Le format exact de la réponse dépend de l'environnement d'exécution. L'exemple de réponse est au format 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",
}
}
}Pour en savoir plus, consultez la documentation de référence sur le rapport Query Explain.
Interpréter les résultats et apporter des ajustements
Prenons un exemple de scénario dans lequel nous interrogeons des films par genre et pays de production.
Pour illustrer cela, supposons l'équivalent de cette requête SQL.
SELECT * FROM /movies WHERE category = 'Romantic' AND country = 'USA';
Si nous utilisons l'option d'analyse, les métriques renvoyées indiquent que la requête s'exécute sur deux index à un seul champ, (category ASC, __name__ ASC) et (country ASC, __name__ ASC). Elle analyse 16 500 entrées d'index, mais ne renvoie que 1 200 documents.
// 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", } } }
Pour optimiser les performances d'exécution de la requête, vous pouvez créer un index composite entièrement couvert (category ASC, country ASC, __name__ ASC).
En exécutant à nouveau la requête avec l'option d'analyse, nous constatons que l'index nouvellement créé est sélectionné pour cette requête, et que la requête s'exécute beaucoup plus rapidement et efficacement.
// 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", } } }