Query Explain verwenden

Mit Query Explain können Sie Abfragen im Datastore-Modus senden an das Back-End senden und detaillierte Leistungsstatistiken zur Ausführung von Back-End-Abfragen erhalten. im Gegenzug erhalten. Sie funktioniert in vielen Fällen wie die EXPLAIN ANALYZE-Operation. relationale Datenbanksysteme.

Sie können Query Explain-Anfragen mit der Clientbibliotheken im Datastore-Modus.

Die Ergebnisse von Query Explain zeigen, wie Ihre Abfragen ausgeführt werden, Ihnen Ineffizienzen und mögliche Engpässe auf Serverseite anzeigen.

Erklärende Abfrage:

  • Bietet Einblicke in die Planungsphase, sodass Sie Ihre Abfrageindexe anpassen und die Effizienz steigern können.
  • Hilft Ihnen, Ihre Kosten und Leistung pro Abfrage zu verstehen können Sie schnell verschiedene Abfragemuster durchlaufen, ihre Nutzung optimieren.

Optionen von Query Explain verstehen: Standard und Analyse

Query Explain-Vorgänge können mit den default-Option oder Analyse-Option.

Bei der Standardoption plant Query Explain die Abfrage, überspringt aber der Ausführungsphase. Dadurch werden Informationen zur Planerphase zurückgegeben. Sie können können Sie so prüfen, ob eine Abfrage über die erforderlichen Indexe verfügt, und ermitteln, Indexe verwendet werden. So können Sie beispielsweise überprüfen, ist die Verwendung eines zusammengesetzten Index, unterschiedliche Indexe zu erstellen.

Mit der Option „Analysieren“ plant Query Explain und führt Abfrage. Dadurch werden alle zuvor genannten Informationen zum Planer sowie Statistiken zur Ausführungszeit der Abfrage zurückgegeben. Dies beinhaltet die Abrechnung Informationen sowie Einblicke auf Systemebene zur Ausführung der Abfrage. Sie können verschiedene Abfrage- und Indexkonfigurationen zu testen, Kosten und Latenz optimieren können.

Was kostet Query Explain?

Wenn eine Abfrage mit der Standardoption erläutert wird, werden keine Index- oder Lesevorgänge ausgeführt. Unabhängig von der Komplexität der Abfrage ist ein Lesevorgang geladen wurde.

Wenn eine Abfrage mit der Analyseoption erklärt wird, durchgeführt werden, und wird Ihnen die Abfrage wie gewohnt in Rechnung gestellt. Für die Analyseaktivität fallen keine zusätzlichen Kosten an, nur die üblichen Kosten für die ausgeführte Abfrage.

Abfrage mit der Standardoption ausführen

Sie können eine Clientbibliothek verwenden, um eine Standardoptionsanfrage zu senden.

Beachten Sie, dass die Erläuterungsergebnisse von Abfrageergebnissen mit Identity and Access Management authentifiziert werden. mit denselben Berechtigungen für reguläre Abfragevorgänge.

Java

Informationen zum Installieren und Verwenden der Clientbibliothek für den Datastore-Modus finden Sie hier. Weitere Informationen finden Sie in der Java API im Datastore-Modus Referenzdokumentation.

Richten Sie Standardanmeldedaten für Anwendungen ein, um sich im Datastore-Modus zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.


import com.google.cloud.datastore.Datastore;
import com.google.cloud.datastore.DatastoreOptions;
import com.google.cloud.datastore.Entity;
import com.google.cloud.datastore.Query;
import com.google.cloud.datastore.QueryResults;
import com.google.cloud.datastore.models.ExplainMetrics;
import com.google.cloud.datastore.models.ExplainOptions;
import com.google.cloud.datastore.models.PlanSummary;
import java.util.List;
import java.util.Map;
import java.util.Optional;

public class QueryProfileExplain {
  public static void invoke() throws Exception {
    // Instantiates a client
    Datastore datastore = DatastoreOptions.getDefaultInstance().getService();

    // Build the query
    Query<Entity> query = Query.newEntityQueryBuilder().setKind("Task").build();

    // Set the explain options to get back *only* the plan summary
    QueryResults<Entity> results = datastore.run(query, ExplainOptions.newBuilder().build());

    // Get the explain metrics
    Optional<ExplainMetrics> explainMetrics = results.getExplainMetrics();
    if (!explainMetrics.isPresent()) {
      throw new Exception("No explain metrics returned");
    }
    PlanSummary planSummary = explainMetrics.get().getPlanSummary();
    List<Map<String, Object>> indexesUsed = planSummary.getIndexesUsed();
    System.out.println("----- Indexes Used -----");
    indexesUsed.forEach(map -> map.forEach((key, val) -> System.out.println(key + ": " + val)));
  }
}

Weitere Informationen zu Indexen finden Sie im Feld indexes_used in der Antwort. im Abfrageplan verwendet:

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

Weitere Informationen zum Bericht finden Sie unter Berichtsreferenz

Abfrage mit der Option „Analysieren“ ausführen

Sie können eine Clientbibliothek verwenden, um eine Anfrage für die Standardoption zu senden.

Beachten Sie, dass die Ergebnisse der Abfrageanalyse mit Identity and Access Management (IAM) authentifiziert werden. mit denselben Berechtigungen für reguläre Abfragevorgänge.

Java

Informationen zum Installieren und Verwenden der Clientbibliothek für den Datastore-Modus finden Sie unter Clientbibliotheken im Datastore-Modus. Weitere Informationen finden Sie in der Java API im Datastore-Modus Referenzdokumentation.

Richten Sie Standardanmeldedaten für Anwendungen ein, um sich im Datastore-Modus zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

import com.google.cloud.datastore.Datastore;
import com.google.cloud.datastore.DatastoreOptions;
import com.google.cloud.datastore.Entity;
import com.google.cloud.datastore.Query;
import com.google.cloud.datastore.QueryResults;
import com.google.cloud.datastore.models.ExecutionStats;
import com.google.cloud.datastore.models.ExplainMetrics;
import com.google.cloud.datastore.models.ExplainOptions;
import com.google.cloud.datastore.models.PlanSummary;
import java.util.List;
import java.util.Map;

public class QueryProfileExplainAnalyze {
  public static void invoke() throws Exception {
    // Instantiates a client
    Datastore datastore = DatastoreOptions.getDefaultInstance().getService();

    // Build the query
    Query<Entity> query = Query.newEntityQueryBuilder().setKind("Task").build();

    // Set explain options with analzye = true to get back the query stats, plan info, and query
    // results
    QueryResults<Entity> results =
        datastore.run(query, ExplainOptions.newBuilder().setAnalyze(true).build());

    // Get the result set stats
    if (!results.getExplainMetrics().isPresent()) {
      throw new Exception("No explain metrics returned");
    }
    ExplainMetrics explainMetrics = results.getExplainMetrics().get();

    // Get the execution stats
    if (!explainMetrics.getExecutionStats().isPresent()) {
      throw new Exception("No execution stats returned");
    }

    ExecutionStats executionStats = explainMetrics.getExecutionStats().get();
    Map<String, Object> debugStats = executionStats.getDebugStats();
    System.out.println("----- Debug Stats -----");
    debugStats.forEach((key, val) -> System.out.println(key + ": " + val));
    System.out.println("----------");

    long resultsReturned = executionStats.getResultsReturned();
    System.out.println("Results returned: " + resultsReturned);

    // Get the plan summary
    PlanSummary planSummary = explainMetrics.getPlanSummary();
    List<Map<String, Object>> indexesUsed = planSummary.getIndexesUsed();
    System.out.println("----- Indexes Used -----");
    indexesUsed.forEach(map -> map.forEach((key, val) -> System.out.println(key + ": " + val)));

    if (!results.hasNext()) {
      throw new Exception("query yielded no results");
    }

    // Get the query results
    System.out.println("----- Query Results -----");
    while (results.hasNext()) {
      Entity entity = results.next();
      System.out.printf("Entity: %s%n", entity);
    }
  }
}

Im Objekt executionStats finden Sie Informationen zur Abfrageprofilerstellung, z. B.:

{
    "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",
               }
    }
}

Weitere Informationen zum Bericht finden Sie unter Berichtsreferenz

Ergebnisse interpretieren und Anpassungen vornehmen

Im folgenden Beispielszenario werden Filme nach Genre und des Produktionslandes und zeigt, wie die Indizes optimiert werden können, Abfrage.

Weitere Informationen zum Bericht finden Sie unter In der Referenz zum Bericht „Query Explain“

Nehmen wir zur Veranschaulichung an, dass das Äquivalent zu dieser SQL-Abfrage verwendet wird.

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

Mit der Option „Analysieren“ wird der folgende Bericht ausgegeben: wird die Abfrage auf den Einzelfeldindexen (category ASC, __name__ ASC) und (country ASC, __name__ ASC). Es scannt 16.500 Indexeinträge, gibt aber nur 1200 Dokumente.

// Output query planning info
"indexes_used": [
    {"query_scope": "Collection Group", "properties": "(category ASC, __name__ ASC)"},
    {"query_scope": "Collection Group", "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",
               }
    }
}

Um die Leistung beim Ausführen der Abfrage zu optimieren, können Sie einen vollständig abgedeckter zusammengesetzter Index (Kategorie ASC, Land ASC, __name__ ASC).

Wenn wir die Abfrage erneut im Analysemodus ausführen, sehen wir, dass die neu erstellten Index für diese Abfrage ausgewählt, die Abfrage wird viel schneller und öfter ausgeführt effizient kommunizieren können.

// Output query planning info
    "indexes_used": [
        {"query_scope": "Collection Group", "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",
               }
    }
}

Nächste Schritte