Spanner bietet integrierte Tabellen, in denen viele Statistiken für die Abfragen und DML-Anweisungen mit der höchsten CPU-Auslastung sowie alle Abfragen insgesamt (einschließlich Änderungsstream-Abfragen) gespeichert werden.
Verfügbarkeit
SPANNER_SYS
-Daten sind nur über SQL-Schnittstellen verfügbar. Beispiel:
Auf der Seite von Spanner Studio einer Datenbank in der Google Cloud Console
Befehl
gcloud spanner databases execute-sql
Dashboards mit Abfragestatistiken
Mit der
executeQuery
API
Andere von Spanner bereitgestellte Methoden für einzelne Leseaufrufe werden nicht unterstützt
SPANNER_SYS
Nach Abfrage gruppierte CPU-Nutzung
In den folgenden Tabellen werden die Abfragen mit der höchsten CPU-Auslastung während eines bestimmten Zeitraums nachverfolgt:
SPANNER_SYS.QUERY_STATS_TOP_MINUTE
: Abfragen in Intervallen von 1 MinuteSPANNER_SYS.QUERY_STATS_TOP_10MINUTE
: Abfragen in Intervallen von 10 MinutenSPANNER_SYS.QUERY_STATS_TOP_HOUR
: Abfragen in Intervallen von 1 Stunde
Diese Tabellen haben folgende Attribute:
Jede Tabelle enthält Daten für nicht überlappende Zeitintervalle in der Länge, die der Tabellenname festlegt.
Die Intervalle beziehen sich auf die Uhrzeit. 1-Minuten-Intervalle enden nach einer vollen Minute, 10-Minuten-Intervalle enden alle 10 Minuten ab Beginn der vollen Stunde, 1-Stunden-Intervalle enden zu jeder vollen Stunde.
Beispielsweise sind die neuesten, für SQL-Abfragen verfügbaren Intervalle um 11:59:30 Uhr:
- 1 Minute: 11:58:00–11:58:59 Uhr
- 10 Minuten: 11:40:00–11:49:59 Uhr
- 1 Stunde: 10:00:00–10:59:59 Uhr
Spanner gruppiert die Statistiken nach dem Text der SQL-Abfrage. Wenn eine Abfrage Abfrageparameter verwendet, Spanner gruppiert alle Ausführungen dieser Abfrage in einer Zeile. Wenn die Abfrage String-Literale verwendet, gruppiert Spanner die Statistiken nur, wenn die vollständigen Abfragetext ist identisch; Wenn sich der Text unterscheidet, wird jede Suchanfrage als separaten Zeile. Bei Batch-DML normalisiert Spanner den Batch, indem aufeinanderfolgende identische Anweisungen dedupliziert werden, bevor der Fingerabdruck generiert wird.
Wenn ein Anfrage-Tag vorhanden ist, ist FPRINT der Hash des Anfrage-Tags. Andernfalls Es ist der Hash des Werts
TEXT
.Jede Zeile enthält Statistiken für alle Ausführungen einer bestimmten SQL-Abfrage für die Spanner während des angegebenen Intervalls Statistiken erfasst.
Wenn Spanner nicht alle Abfragen speichern kann, die während des Intervalls ausgeführt werden, priorisiert das System Abfragen mit der höchsten CPU-Auslastung während der angegebenen Intervall.
Verfolgte Abfragen umfassen Abfragen, die abgeschlossen, fehlgeschlagen oder vom Nutzer abgebrochen wurden.
Eine Teilmenge der Statistiken bezieht sich auf Abfragen, die ausgeführt, aber nicht abgeschlossen wurden:
Ausführungsanzahl und durchschnittliche Latenz in Sekunden für alle Abfragen, die nicht erfolgreich waren.
Ausführungsanzahl für Abfragen, die zu einer Zeitüberschreitung geführt haben.
Ausführungsanzahl für Abfragen, die vom Nutzer abgebrochen oder aufgrund von Problemen mit der Netzwerkverbindung fehlgeschlagen sind.
Für alle Spalten in den Tabellen sind Nullwerte zulässig.
Tabellenschema
Spaltenname | Typ | Beschreibung | |
---|---|---|---|
INTERVAL_END |
TIMESTAMP |
Ende des Zeitintervalls, in dem die eingeschlossene Abfrage ausgeführt wurde | |
REQUEST_TAG |
STRING |
Das optionale Anfrage-Tag für diesen Abfragevorgang. Weitere Informationen zur Verwendung von Tags finden Sie unter Fehlerbehebung bei Anfrage-Tags. | |
QUERY_TYPE |
STRING |
Gibt an, ob eine Abfrage ein PARTITIONED_QUERY - oder
QUERY . Ein PARTITIONED_QUERY
ist eine Abfrage mit einem partitionToken, die von der PartitionQuery API abgerufen wurde. Alle
Die anderen Abfragen und DML-Anweisungen sind mit QUERY gekennzeichnet.
Abfragetyp.
Abfragestatistiken für
Partitionierte DMLs sind
nicht unterstützt.
|
|
TEXT |
STRING |
SQL-Abfragetext, verkürzt auf ca. 64 KB
Statistiken für mehrere Abfragen, die denselben Tag-String haben, werden in einer einzelnen Zeile gruppiert, wobei REQUEST_TAG mit diesem Tag-String übereinstimmt. In diesem Feld wird nur der Text einer dieser Abfragen angezeigt, verkürzt auf ca. 64 KB.
Bei der Batch-DML werden die SQL-Anweisungen in eine einzige Zeile umgewandelt und mit einem Semikolon als Trennzeichen zusammengefügt. Aufeinanderfolgende identische SQL-Abfragen
Texte werden vor dem Abschneiden dedupliziert.
|
|
TEXT_TRUNCATED |
BOOL |
Ob der Abfragetext gekürzt wurde oder vollständig ist | |
TEXT_FINGERPRINT |
INT64 |
Der Hash des Werts REQUEST_TAG , falls vorhanden; andernfalls der Hash des Werts TEXT . |
|
EXECUTION_COUNT |
INT64 |
Gibt an, wie oft Spanner die Abfrage während des Intervalls gesehen hat. | |
AVG_LATENCY_SECONDS |
FLOAT64 |
Durchschnittliche Zeit in Sekunden für jede Abfrageausführung in der Datenbank; dieser Durchschnitt schließt die Codierungs- und Übertragungszeit für die Ergebnismenge sowie den Aufwand aus. | |
AVG_ROWS |
FLOAT64 |
Durchschnittliche Anzahl der Zeilen, die die Abfrage zurückgegeben hat | |
AVG_BYTES |
FLOAT64 |
Die durchschnittliche Anzahl der von der Abfrage zurückgegebenen Datenbyte, ohne den Aufwand der Übertragungskodierung | |
AVG_ROWS_SCANNED |
FLOAT64 |
Durchschnittliche Anzahl der Zeilen, die von der Abfrage gescannt wurden, ausgenommen gelöschte Werte | |
AVG_CPU_SECONDS |
FLOAT64 |
Durchschnittliche Anzahl von Sekunden der CPU-Zeit, die Spanner zum Ausführen der Abfrage für alle Vorgänge aufgewendet hat | |
ALL_FAILED_EXECUTION_COUNT |
INT64 |
Häufigkeit, mit der die Abfrage während des Intervalls fehlgeschlagen ist. | |
ALL_FAILED_AVG_LATENCY_SECONDS |
FLOAT64 |
Durchschnittliche Zeit in Sekunden für jede Abfrageausführung, die in der Datenbank fehlgeschlagen ist dieser Durchschnitt schließt die Codierungs- und Übertragungszeit für die Ergebnismenge sowie den Aufwand aus. | |
CANCELLED_OR_DISCONNECTED_EXECUTION_COUNT |
INT64 |
Häufigkeit, mit der die Abfrage vom Nutzer abgebrochen oder aufgrund einer unterbrochenen Netzwerkverbindung während des Intervalls abgebrochen wurde. | |
TIMED_OUT_EXECUTION_COUNT |
INT64 |
Häufigkeit, mit der die Abfrage während des Intervalls das Zeitlimit überschritten hat. | |
AVG_BYTES_WRITTEN |
FLOAT64 |
Durchschnittliche Anzahl der von der Anweisung geschriebenen Byte. | |
AVG_ROWS_WRITTEN |
FLOAT64 |
Durchschnittliche Anzahl der Zeilen, die von der Anweisung geändert wurden. | |
STATEMENT_COUNT |
INT64 |
Die Summe der in diesem Eintrag zusammengefassten Anweisungen. Für normale Abfragen und DML entsprechen, entspricht dies der Anzahl der Ausführungen. Für Batch-DML: Spanner erfasst die Anzahl der Anweisungen im Batch. | |
RUN_IN_RW_TRANSACTION_EXECUTION_COUNT |
INT64 |
Die Häufigkeit, mit der die Abfrage als Teil einer Lese-Schreib-Transaktion ausgeführt wurde. Mithilfe dieser Spalte können Sie ermitteln, ob Sie Konflikte bezüglich Sperren vermeiden können, indem Sie in eine schreibgeschützte Transaktion umwandeln. | |
LATENCY_DISTRIBUTION |
ARRAY<STRUCT> |
Ein Histogramm der Abfrageausführungszeit. Die Werte sind in Sekunden gemessen werden.
Das Array enthält ein einzelnes Element und hat den folgenden Typ:
Um die Perzentillatenz aus der Verteilung zu berechnen,
verwenden Sie die Funktion Weitere Informationen finden Sie unter Perzentile und Verteilungswerte. |
|
AVG_MEMORY_PEAK_USAGE_BYTES |
FLOAT64 |
Die durchschnittliche maximale Arbeitsspeichernutzung während einer verteilten Abfrageausführung in Byte. Anhand dieser Statistik können Sie ermitteln, bei welchen Abfragen oder Tabellendatengrößen wahrscheinlich Speicherlimits erreicht werden. |
|
AVG_MEMORY_USAGE_PERCENTAGE |
FLOAT64 |
Die durchschnittliche Arbeitsspeichernutzung während der Ausführung einer verteilten Abfrage (als Prozentsatz des für diese Abfrage zulässigen Arbeitsspeicherlimits). Diese Statistik verfolgt nur den Arbeitsspeicher, der für die Abfrage
ausführen können. Einige Operatoren verwenden zusätzlichen Pufferspeicher, um
die Leistung. Der zusätzliche verwendete Pufferspeicher ist im Abfrageplan zu sehen, wird aber nicht zur Berechnung von Verwenden Sie diese Statistik, um Abfragen zu identifizieren, die sich dem Arbeitsspeicher nähern Nutzungslimit überschritten und das Risiko eines Fehlers droht, wenn die Datenmenge zunimmt. Bis das Risiko eines Abfragefehlers zu mindern, siehe Best Practices für SQL, um diese Abfragen zu optimieren oder die Abfrage in Teile zu unterteilen, die weniger Daten lesen. |
|
AVG_QUERY_PLAN_CREATION_TIME_SECS |
FLOAT64 |
Die durchschnittliche CPU-Zeit in Sekunden, die für die Abfragekompilierung benötigt wurde, einschließlich Erstellung der Abfragelaufzeit. Wenn der Wert dieser Spalte hoch ist, verwenden Sie parametisierte Abfragen. |
|
AVG_FILESYSTEM_DELAY_SECS |
FLOAT64 |
Die durchschnittliche Zeit, die die Abfrage für das Lesen aus dem Dateisystem benötigt oder bei der Blockierung durch E/A (Eingabe/Ausgabe) verbraucht. Mit dieser Statistik können Sie eine potenzielle hohe Latenz identifizieren, die durch die E/A-Vorgänge des Dateisystems verursacht wird. Fügen Sie einen Index hinzu, um das Problem zu beheben.
oder |
|
AVG_REMOTE_SERVER_CALLS |
FLOAT64 |
Die durchschnittliche Anzahl der Remote-Serveraufrufe (RPC), die durch die Abfrage abgeschlossen wurden. Anhand dieser Statistik können Sie ermitteln, ob verschiedene Abfragen, die denselben
Anzahl der Zeilen eine sehr
unterschiedliche Anzahl von RPCs hat. Die Abfrage mit einem
Wenn Sie einen Index hinzufügen, kann es von Vorteil sein, einen höheren RPC-Wert zu erzielen.
oder eine
Klausel |
|
AVG_ROWS_SPOOLED |
FLOAT64 |
Die durchschnittliche Anzahl der Zeilen, die von der Abfrageanweisung auf ein temporäres Laufwerk (nicht im Arbeitsspeicher) geschrieben wurden. Anhand dieser Statistik können Sie Abfragen mit potenziell hoher Latenz ermitteln, die speicherintensiv sind und nicht speicherintern ausgeführt werden können. Um das Risiko zu minimieren,
Ändern Sie die |
EXECUTION_COUNT
, AVG_LATENCY_SECONDS
und LATENCY_DISTRIBUTION
für fehlgeschlagen
Abfragen enthalten Abfragen, bei denen aufgrund falscher Syntax Fehler aufgetreten sind oder bei denen ein Fehler aufgetreten ist
Vorübergehender Fehler, aber neuer Versuch.
Zusammengefasste Statistiken
Außerdem gibt es Tabellen, in denen zusammengefasste Daten für alle Abfragen nachverfolgt werden, für die Spanner Statistiken für einen bestimmten Zeitraum erfasst:
SPANNER_SYS.QUERY_STATS_TOTAL_MINUTE
: Abfragen in Intervallen von 1 MinuteSPANNER_SYS.QUERY_STATS_TOTAL_10MINUTE
: Abfragen in Intervallen von 10 MinutenSPANNER_SYS.QUERY_STATS_TOTAL_HOUR
: Abfragen in Intervallen von 1 Stunde
Diese Tabellen haben folgende Attribute:
Jede Tabelle enthält Daten für nicht überlappende Zeitintervalle in der Länge, die der Tabellenname festlegt.
Die Intervalle beziehen sich auf die Uhrzeit. 1-Minuten-Intervalle enden nach einer vollen Minute, 10-Minuten-Intervalle enden alle 10 Minuten ab Beginn der vollen Stunde, 1-Stunden-Intervalle enden zu jeder vollen Stunde.
Beispielsweise sind die neuesten, für SQL-Abfragen verfügbaren Intervalle um 11:59:30 Uhr:
- 1 Minute: 11:58:00–11:58:59 Uhr
- 10 Minuten: 11:40:00–11:49:59 Uhr
- 1 Stunde: 10:00:00–10:59:59 Uhr
Jede Zeile enthält zusammengefasste Statistiken für alle Abfragen, die während des angegebenen Intervalls über die Datenbank ausgeführt werden. Es gibt nur eine Zeile pro Zeitintervall und enthält abgeschlossene Abfragen, fehlgeschlagene Abfragen und vom Nutzer abgebrochene Abfragen.
Die in den
TOTAL
-Tabellen erfassten Statistiken können Abfragen enthalten, die Spanner hat in denTOP
-Tabellen nicht erfasst.Einige Spalten in diesen Tabellen werden in Cloud Monitoring als Messwerte angezeigt. Folgende Messwerte stehen zur Verfügung:
- Anzahl der Abfrageausführungen
- Abfragefehler
- Abfragelatenzen
- Anzahl der zurückgegebenen Zeilen
- Anzahl gescannter Zeilen
- Anzahl der zurückgegebenen Byte
- CPU-Zeit für Abfrage
Weitere Informationen finden Sie unter Spanner-Messwerte.
Tabellenschema
Spaltenname | Typ | Beschreibung |
---|---|---|
INTERVAL_END |
TIMESTAMP |
Ende des Zeitintervalls, in dem die eingeschlossene Abfrage ausgeführt wurde |
EXECUTION_COUNT |
INT64 |
Gibt an, wie oft Spanner die Abfrage während des Zeitintervalls gesehen hat. |
AVG_LATENCY_SECONDS |
FLOAT64 |
Durchschnittliche Zeit in Sekunden für jede Abfrageausführung in der Datenbank; dieser Durchschnitt schließt die Codierungs- und Übertragungszeit für die Ergebnismenge sowie den Aufwand aus. |
AVG_ROWS |
FLOAT64 |
Durchschnittliche Anzahl der Zeilen, die die Abfrage zurückgegeben hat |
AVG_BYTES |
FLOAT64 |
Die durchschnittliche Anzahl der von der Abfrage zurückgegebenen Datenbyte, ohne den Aufwand der Übertragungskodierung |
AVG_ROWS_SCANNED |
FLOAT64 |
Durchschnittliche Anzahl der Zeilen, die von der Abfrage gescannt wurden, ausgenommen gelöschte Werte |
AVG_CPU_SECONDS |
FLOAT64 |
Durchschnittliche Anzahl von Sekunden der CPU-Zeit, die Spanner zum Ausführen der Abfrage für alle Vorgänge aufgewendet hat |
ALL_FAILED_EXECUTION_COUNT |
INT64 |
Häufigkeit, mit der die Abfrage während des Intervalls fehlgeschlagen ist. |
ALL_FAILED_AVG_LATENCY_SECONDS |
FLOAT64 |
Durchschnittliche Zeit in Sekunden für jede Abfrageausführung, die in der Datenbank fehlgeschlagen ist dieser Durchschnitt schließt die Codierungs- und Übertragungszeit für die Ergebnismenge sowie den Aufwand aus. |
CANCELLED_OR_DISCONNECTED_EXECUTION_COUNT |
INT64 |
Häufigkeit, mit der die Abfrage vom Nutzer abgebrochen oder aufgrund einer unterbrochenen Netzwerkverbindung während des Intervalls abgebrochen wurde. |
TIMED_OUT_EXECUTION_COUNT |
INT64 |
Häufigkeit, mit der die Abfrage während des Intervalls das Zeitlimit überschritten hat. |
AVG_BYTES_WRITTEN |
FLOAT64 |
Durchschnittliche Anzahl der von der Anweisung geschriebenen Byte. |
AVG_ROWS_WRITTEN |
FLOAT64 |
Durchschnittliche Anzahl der Zeilen, die von der Anweisung geändert wurden. |
RUN_IN_RW_TRANSACTION_EXECUTION_COUNT |
INT64 |
Die Häufigkeit, mit der Abfragen als Teil von Lese-Schreib-Transaktionen ausgeführt wurden. Mithilfe dieser Spalte können Sie ermitteln, ob Sie Konflikte bezüglich Sperren vermeiden können, indem Sie einige Abfragen auf schreibgeschützte Transaktionen. |
LATENCY_DISTRIBUTION |
ARRAY<STRUCT> |
Ein Histogramm der Ausführungszeit für alle Abfragen. Die Werte werden in Sekunden gemessen.
Geben Sie das Array so an:
Verwenden Sie die Funktion Weitere Informationen finden Sie unter Perzentile und Verteilungswerte. |
Datenaufbewahrung
Spanner speichert die Daten für jede Tabelle mindestens für die folgenden Zeiträume:
SPANNER_SYS.QUERY_STATS_TOP_MINUTE
undSPANNER_SYS.QUERY_STATS_TOTAL_MINUTE
: Intervalle der letzten 6 Stunden.SPANNER_SYS.QUERY_STATS_TOP_10MINUTE
undSPANNER_SYS.QUERY_STATS_TOTAL_10MINUTE
: Intervalle der letzten 4 Tage.SPANNER_SYS.QUERY_STATS_TOP_HOUR
undSPANNER_SYS.QUERY_STATS_TOTAL_HOUR
: Intervalle der letzten 30 Tage.
Beispielabfragen
Dieser Abschnitt enthält mehrere Beispiel-SQL-Anweisungen, die Abfragestatistiken abrufen. Sie können diese SQL-Anweisungen mit der Methode Clientbibliotheken, die Google Cloud CLI oder die Google Cloud Console:
Grundlegende Statistiken für jede Abfrage in einem bestimmten Zeitraum auflisten
Die folgende Abfrage gibt die Rohdaten für die Top-Abfragen der vorherigen Minute zurück:
SELECT text,
request_tag,
interval_end,
execution_count,
avg_latency_seconds,
avg_rows,
avg_bytes,
avg_rows_scanned,
avg_cpu_seconds
FROM spanner_sys.query_stats_top_minute
ORDER BY interval_end DESC;
Abfragen mit der höchsten CPU-Nutzung auflisten
Die folgende Abfrage gibt die Abfragen mit der höchsten CPU-Nutzung der vorherigen Stunde zurück:
SELECT text,
request_tag,
execution_count AS count,
avg_latency_seconds AS latency,
avg_cpu_seconds AS cpu,
execution_count * avg_cpu_seconds AS total_cpu
FROM spanner_sys.query_stats_top_hour
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_top_hour)
ORDER BY total_cpu DESC;
Gesamtzahl der Ausführungen in einem bestimmten Zeitraum ermitteln
Die folgende Abfrage gibt die Gesamtzahl der im letzten vollständigen 1-Minuten-Intervall ausgeführten Abfragen zurück:
SELECT interval_end,
execution_count
FROM spanner_sys.query_stats_total_minute
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_top_minute);
Durchschnittliche Latenz einer Abfrage ermitteln
Die folgende Abfrage gibt die durchschnittliche Latenzzeit für eine bestimmte Abfrage zurück:
SELECT avg_latency_seconds
FROM spanner_sys.query_stats_top_hour
WHERE text LIKE "SELECT x FROM table WHERE x=@foo;";
Latenz für das 99. Perzentil für Abfragen ermitteln
Die folgende Abfrage gibt das 99. Perzentil der Ausführungszeit für Abfragen zurück, die in den letzten 10 Minuten ausgeführt wurden:
SELECT interval_end, avg_latency_seconds, SPANNER_SYS.DISTRIBUTION_PERCENTILE(latency_distribution[OFFSET(0)], 99.0)
AS percentile_latency
FROM spanner_sys.query_stats_total_10minute
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_total_10minute)
ORDER BY interval_end;
Wenn Sie die durchschnittliche Latenz mit der Latenz des 99. Perzentils vergleichen, können Sie mögliche Ausreißer bei Abfragen mit hoher Ausführungszeit identifizieren.
Abfragen finden, die die meisten Daten scannen
Sie können die Anzahl der von einer Abfrage gescannten Zeilen als Maß für die Datenmenge verwenden, die von der Abfrage gescannt wurde. Die folgende Abfrage gibt die Anzahl der Zeilen zurück, die von Abfragen gescannt wurden, die in der vorherigen Stunde ausgeführt wurden:
SELECT text,
execution_count,
avg_rows_scanned
FROM spanner_sys.query_stats_top_hour
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_top_hour)
ORDER BY avg_rows_scanned DESC;
Die Aussagen finden, die die meisten Daten verfasst haben
Sie können die Anzahl der von DML geschriebenen (oder geschriebenen Byte) Zeilen als Maß für die Datenmenge, die durch die Abfrage geändert wurde. Die folgende Abfrage gibt den Wert Anzahl der Zeilen, die von DML-Anweisungen geschrieben wurden, die in der vorherigen Stunde ausgeführt wurden:
SELECT text,
execution_count,
avg_rows_written
FROM spanner_sys.query_stats_top_hour
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_top_hour)
ORDER BY avg_rows_written DESC;
Gesamte CPU-Nutzung in allen Abfragen
Die folgende Abfrage gibt die Anzahl der in der vorherigen Stunde verwendeten CPU-Stunden zurück:
SELECT (avg_cpu_seconds * execution_count / 60 / 60)
AS total_cpu_hours
FROM spanner_sys.query_stats_total_hour
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_total_hour);
Abfragen auflisten, die in einem bestimmten Zeitraum fehlgeschlagen sind
Die folgende Abfrage gibt die Rohdaten zurück, einschließlich Ausführungsanzahl und durchschnittlicher Latenz fehlgeschlagener Abfragen für die Top-Abfragen der vorherigen Minute:
SELECT text,
request_tag,
interval_end,
execution_count,
all_failed_execution_count,
all_failed_avg_latency_seconds,
avg_latency_seconds,
avg_rows,
avg_bytes,
avg_rows_scanned,
avg_cpu_seconds
FROM spanner_sys.query_stats_top_minute
WHERE all_failed_execution_count > 0
ORDER BY interval_end;
Gesamtfehleranzahl in einem bestimmten Zeitraum ermitteln
Die folgende Abfrage gibt die Gesamtzahl der Abfragen zurück, die im letzten vollständigen 1-Minuten-Intervall nicht ausgeführt werden konnten.
SELECT interval_end,
all_failed_execution_count
FROM spanner_sys.query_stats_total_minute
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_top_minute)
ORDER BY interval_end;
Abfragen mit den meisten Zeitüberschreitungen auflisten
Die folgende Abfrage gibt die Abfragen mit der höchsten Zeitüberschreitung in der vorherigen Stunde zurück.
SELECT text,
execution_count AS count,
timed_out_execution_count AS timeout_count,
avg_latency_seconds AS latency,
avg_cpu_seconds AS cpu,
execution_count * avg_cpu_seconds AS total_cpu
FROM spanner_sys.query_stats_top_hour
WHERE interval_end =
(SELECT MAX(interval_end)
FROM spanner_sys.query_stats_top_hour)
ORDER BY timed_out_execution_count DESC;
Durchschnittliche Latenz erfolgreicher und fehlgeschlagener Ausführungen einer Abfrage ermitteln
Die folgende Abfrage gibt die kombinierte durchschnittliche Latenz, die durchschnittliche Latenz für erfolgreiche Ausführungen und die durchschnittliche Latenz für fehlgeschlagene Ausführungen für eine bestimmte Abfrage zurück.
SELECT avg_latency_seconds AS combined_avg_latency,
all_failed_avg_latency_seconds AS failed_execution_latency,
( avg_latency_seconds * execution_count -
all_failed_avg_latency_seconds * all_failed_execution_count
) / (
execution_count - all_failed_execution_count ) AS success_execution_latency
FROM spanner_sys.query_stats_top_hour
WHERE text LIKE "select x from table where x=@foo;";
Probleme mit hoher CPU-Auslastung oder erhöhter Abfragelatenz mithilfe von Abfragestatistiken beheben
Abfragestatistiken sind nützlich, wenn Sie eine hohe CPU-Auslastung in Ihrer Spanner-Datenbank untersuchen oder einfach nur die CPU-intensiven Abfrageformen in Ihrer Datenbank verstehen möchten. Abfragen mit signifikanten Datenbankressourcen bietet Spanner-Nutzern die Möglichkeit, Betriebskosten zu senken und möglicherweise allgemeine Systemlatenzen zu verbessern.
Sie können SQL-Code oder das Dashboard Abfragestatistiken verwenden, um problematische Abfragen in Ihrer Datenbank zu untersuchen. Die folgenden erfahren Sie, wie Sie solche Abfragen mithilfe von SQL-Code untersuchen können.
Im folgenden Beispiel liegt der Fokus auf der CPU-Nutzung. Probleme mit erhöhter Abfragelatenz beheben und die Abfragen mit der höchsten Latenzen. Wählen Sie einfach Zeitintervalle und Abfragen nach Latenz anstatt nach CPU-Auslastung aus.
Zeitraum auswählen, der untersucht werden soll
Starten Sie die Prüfung mit der Suche nach einem Zeitpunkt, an dem Ihre Anwendung begann, eine hohe CPU-Auslastung zu verzeichnen. z. B. wenn das Problem erstmals gegen 17:00 Uhr am 24. Juli 2020 (UTC).
Abfragestatistiken für den ausgewählten Zeitraum erfassen
Nachdem ein Zeitraum zum Starten der Prüfung ausgewählt wurde, betrachten wir die Statistikdaten, die etwa zu diesem Zeitpunkt in der Tabelle QUERY_STATS_TOTAL_10MINUTE
gesammelt wurden.
Die Ergebnisse dieser Abfrage können darauf hinweisen, wie sich die CPU und andere Abfragestatistiken in diesem Zeitraum geändert haben.
Die folgende Abfrage gibt die zusammengefassten Abfragestatistiken von 16:30 bis einschließlich 17:30 UTC zurück. Wir verwenden ROUND
in unserer Abfrage, um die Anzahl der Dezimalstellen für Anzeigezwecke einzuschränken.
SELECT interval_end,
execution_count AS count,
ROUND(avg_latency_seconds,2) AS latency,
ROUND(avg_rows,2) AS rows_returned,
ROUND(avg_bytes,2) AS bytes,
ROUND(avg_rows_scanned,2) AS rows_scanned,
ROUND(avg_cpu_seconds,3) AS avg_cpu
FROM spanner_sys.query_stats_total_10minute
WHERE
interval_end >= "2020-07-24T16:30:00Z"
AND interval_end <= "2020-07-24T17:30:00Z"
ORDER BY interval_end;
Die Abfrage liefert folgende Ergebnisse.
interval_end | count | Latenz | rows_returned | Byte | rows_scanned | avg_cpu |
---|---|---|---|---|---|---|
2020-07-24T16:30:00Z | 6 | 0,06 | 5,00 | 536,00 | 16,67 | 0,035 |
2020-07-24T16:40:00Z | 55 | 0,02 | 0.22 | 25,29 | 0.22 | 0,004 |
2020-07-24T16:50:00Z | 102 | 0,02 | 0,30 | 33,35 | 0,30 | 0,004 |
2020-07-24T17:00:00Z |
154 |
1.06 |
4.42 |
486.33 |
7792208.12 |
4.633 |
2020-07-24T17:10:00Z | 94 | 0,02 | 1,68 | 106,84 | 1,68 | 0,006 |
2020-07-24T17:20:00Z | 110 | 0,02 | 0,38 | 34,60 | 0,38 | 0,005 |
2020-07-24T17:30:00Z | 47 | 0,02 | 0.23 | 24,96 | 0.23 | 0,004 |
In der vorherigen Tabelle sehen Sie, dass die durchschnittliche CPU-Zeit (die Spalte avg_cpu) in der Ergebnistabelle in den hervorgehobenen Intervallen um 17:00 Uhr am höchsten ist. Außerdem sehen wir eine durchschnittlich viel höhere Anzahl von Zeilen, die gescannt werden. Dies zeigt an, dass teurere Abfragen zwischen 16:50 und 17:00 Uhr ausgeführt wurden. Intervall auswählen um sie im nächsten Schritt weiter zu untersuchen.
Abfragen mit hoher CPU-Auslastung ermitteln
Wir prüfen nun die ausgewählte Tabelle QUERY_STATS_TOP_10MINUTE
mit einem Zeitintervall, um den ausgewählten Wert zu untersuchen. Die Ergebnisse dieser Abfrage können dabei helfen, zu erkennen, welche Abfragen eine hohe CPU-Auslastung verursachen.
SELECT text_fingerprint AS fingerprint,
execution_count AS count,
ROUND(avg_latency_seconds,2) AS latency,
ROUND(avg_cpu_seconds,3) AS cpu,
ROUND(execution_count * avg_cpu_seconds,3) AS total_cpu
FROM spanner_sys.query_stats_top_10MINUTE
WHERE
interval_end = "2020-07-24T17:00:00Z"
ORDER BY total_cpu DESC;
Die Abfrage liefert folgende Ergebnisse.
Fingerprint | count | Latenz | CPU | total_cpu |
---|---|---|---|---|
5505124206529314852 |
30 |
3.88 |
17.635 |
529.039 |
1697951036096498470 |
10 |
4.49 |
18.388 |
183.882 |
2295109096748351518 | 1 | 0,33 | 0,048 | 0,048 |
11618299167612903606 | 1 | 0,25 | 0,021 | 0,021 |
10302798842433860499 | 1 | 0,04 | 0,006 | 0,006 |
123771704548746223 | 1 | 0,04 | 0,006 | 0,006 |
4216063638051261350 | 1 | 0,04 | 0,006 | 0,006 |
3654744714919476398 | 1 | 0,04 | 0,006 | 0,006 |
2999453161628434990 | 1 | 0,04 | 0,006 | 0,006 |
823179738756093706 | 1 | 0,02 | 0,005 | 0.0056 |
Die beiden wichtigsten Abfragen, die in der Ergebnistabelle hervorgehoben sind, sind Ausreißer in Bezug auf durchschnittliche CPU- und Latenz sowie Anzahl der Ausführungen und Gesamt-CPU. Sehen wir uns die erste Abfrage an, die in diesen Ergebnissen aufgeführt ist.
Abfrageausführungen im Zeitverlauf vergleichen
Nachdem wir die Untersuchung eingegrenzt haben, können wir uns der Tabelle QUERY_STATS_TOP_MINUTE
widmen. Durch den Vergleich von Durchläufen für eine bestimmte Abfrage können wir nach Korrelationen zwischen der Anzahl der zurückgegebenen Zeilen oder Byte oder der Anzahl der gescannten und erhöhten CPUs oder Latenzen suchen. Eine Abweichung kann auf eine Ungleichförmigkeit in den Daten hinweisen. Eine konstant hohe Anzahl von gescannten Zeilen kann auf das Fehlen der entsprechenden Indexe oder der nicht optimalen Join-Reihenfolge hinweisen.
Prüfen Sie die Abfrage mit der höchsten durchschnittlichen CPU-Auslastung und der höchsten CPU-Auslastung Latenz, indem Sie die folgende Anweisung ausführen, die nach dem text_fingerprint filtert, dieser Abfrage.
SELECT interval_end,
ROUND(avg_latency_seconds,2) AS latency,
avg_rows AS rows_returned,
avg_bytes AS bytes_returned,
avg_rows_scanned AS rows_scanned,
ROUND(avg_cpu_seconds,3) AS cpu,
FROM spanner_sys.query_stats_top_minute
WHERE text_fingerprint = 5505124206529314852
ORDER BY interval_end DESC;
Die Abfrage liefert folgende Ergebnisse.
interval_end | Latenz | rows_returned | bytes_returned | rows_scanned | CPU |
---|---|---|---|---|---|
2020-07-24T17:00:00Z | 4.55 | 21 | 2365 | 30000000 | 19.255 |
2020-07-24T16:00:00Z | 3,62 | 21 | 2365 | 30000000 | 17,255 |
2020-07-24T15:00:00Z | 4,37 | 21 | 2365 | 30000000 | 18,350 |
2020-07-24T14:00:00Z | 4,02 | 21 | 2365 | 30000000 | 17,748 |
2020-07-24T13:00:00Z | 3.12 | 21 | 2365 | 30000000 | 16,380 |
2020-07-24T12:00:00Z | 3,45 | 21 | 2365 | 30000000 | 15,476 |
2020-07-24T11:00:00Z | 4,94 | 21 | 2365 | 30000000 | 22,611 |
2020-07-24T10:00:00Z | 6,48 | 21 | 2365 | 30000000 | 21,265 |
2020-07-24T09:00:00Z | 0.23 | 21 | 2365 | 5 | 0,040 |
2020-07-24T08:00:00Z | 0,04 | 21 | 2365 | 5 | 0,021 |
2020-07-24T07:00:00Z | 0,09 | 21 | 2365 | 5 | 0,030 |
Bei der Untersuchung der vorhergehenden Ergebnisse sehen wir, dass sich die Anzahl der gescannten Zeilen, die verwendete CPU und die Latenz alle gegen 9:00 Uhr erheblich geändert haben. Um zu verstehen, warum diese Zahlen so drastisch angestiegen sind, untersuchen wir den Abfragetext und prüfen, ob sich Änderungen im Schema auf die Abfrage ausgewirkt haben könnten.
Verwenden Sie die folgende Abfrage, um den Abfragetext für die untersuchte Abfrage abzurufen.
SELECT text,
text_truncated
FROM spanner_sys.query_stats_top_hour
WHERE text_fingerprint = 5505124206529314852
LIMIT 1;
Dies gibt das folgende Ergebnis zurück.
text | text_truncated |
---|---|
select * aus Bestellungen mit o_custkey = 36901; | falsch |
Bei der Überprüfung des zurückgegebenen Abfragetexts sehen wir, dass die Abfrage nach einem Feld namens o_custkey
filtert. Dies ist eine Nicht-Schlüsselspalte in der Tabelle orders
. In diesem Fall war bis zu 9:00 Uhr ein Index für diese Spalte vorhanden. Dies erklärt die Änderung der Kosten für diese Abfrage. Wir können den Index wieder hinzufügen oder, wenn die Abfrage selten ausgeführt wird, entscheiden, dass wir den Index nicht haben und die höheren Lesekosten akzeptieren.
Unsere Untersuchung hat sich bisher auf Abfragen konzentriert, die erfolgreich abgeschlossen wurden, und wir haben einen Grund dafür gefunden, warum die Datenbank eine gewisse Beeinträchtigung der Leistung aufweist. Im nächsten Schritt konzentrieren wir uns auf fehlgeschlagene oder abgebrochene Abfragen und zeigen, wie Sie diese Daten untersuchen können, um weitere Informationen zu erhalten.
Fehlgeschlagene Abfragen untersuchen
Abfragen, die nicht erfolgreich abgeschlossen werden, verbrauchen weiterhin Ressourcen, bevor eine Zeitüberschreitung auftritt, werden abgebrochen oder anderweitig fehlschlagen. Spanner verfolgt die Ausführungsanzahl und Ressourcen, die von fehlgeschlagenen Abfragen zusammen mit erfolgreichen Abfragen verbraucht wurden zu erhalten.
Um zu prüfen, ob fehlgeschlagene Abfragen einen erheblichen Einfluss auf die Systemauslastung haben, können wir zuerst prüfen, wie viele Abfragen im gewünschten Zeitintervall fehlgeschlagen sind.
SELECT interval_end,
all_failed_execution_count AS failed_count,
all_failed_avg_latency_seconds AS latency
FROM spanner_sys.query_stats_total_minute
WHERE
interval_end >= "2020-07-24T16:50:00Z"
AND interval_end <= "2020-07-24T17:00:00Z"
ORDER BY interval_end;
interval_end | failed_count | Latenz |
---|---|---|
2020-07-24T16:52:00Z | 1 | 15,211391 |
2020-07-24T16:53:00Z | 3 | 58,312232 |
Wir können weiter untersuchen, indem wir nach Abfragen suchen, die mit der folgenden Abfrage am wahrscheinlichsten fehlschlagen.
SELECT interval_end,
text_fingerprint,
execution_count,
avg_latency_seconds AS avg_latency,
all_failed_execution_count AS failed_count,
all_failed_avg_latency_seconds AS failed_latency,
cancelled_or_disconnected_execution_count AS cancel_count,
timed_out_execution_count AS to_count
FROM spanner_sys.query_stats_top_minute
WHERE all_failed_execution_count > 0
ORDER BY interval_end;
interval_end | text_fingerprint | execution_count | failed_count | cancel_count | to_count |
---|---|---|---|---|---|
2020-07-24T16:52:00Z | 5505124206529314852 | 3 | 1 | 1 | 0 |
2020-07-24T16:53:00Z | 1697951036096498470 | 2 | 1 | 1 | 0 |
2020-07-24T16:53:00Z | 5505124206529314852 | 5 | 2 | 1 | 1 |
Wie die vorherige Tabelle zeigt, ist die Abfrage mit dem Fingerabdruck 5505124206529314852
in verschiedenen Zeitintervallen mehrmals fehlgeschlagen. Angesichts eines solchen Ausfallmusters ist es interessant, die Latenz erfolgreicher und fehlgeschlagener Ausführungen zu vergleichen.
SELECT interval_end,
avg_latency_seconds AS combined_avg_latency,
all_failed_avg_latency_seconds AS failed_execution_latency,
( avg_latency_seconds * execution_count -
all_failed_avg_latency_seconds * all_failed_execution_count
) / (
execution_count - all_failed_execution_count ) AS success_execution_latency
FROM spanner_sys.query_stats_top_hour
WHERE text_fingerprint = 5505124206529314852;
interval_end | combined_avg_latency | failed_execution_latency | success_execution_latency |
---|---|---|---|
2020-07-24T17:00:00Z | 3,880420 | 13,830709 | 2,774832 |
Best Practices anwenden
Nachdem wir eine Kandidatenabfrage zur Optimierung ermittelt haben, können wir als Nächstes das Abfrageprofil betrachten und versuchen, eine Optimierung mit Best Practices für SQL durchzuführen.
Nächste Schritte
Ermitteln Sie mit der ältesten aktiven Abfragen die am längsten aktiven Abfragen.
Weitere Informationen zu Tools zur Selbstbeobachtung
Weitere Informationen, die Spanner für jede Datenbank speichert, finden Sie in der den Informationsschematabellen der Datenbank.
Best Practices für SQL für Spanner.