Abfrageleistung optimieren
Dieses Dokument enthält die Best Practices zur Optimierung der Abfrageleistung.
Nachdem die Abfrage abgeschlossen wurde, können Sie den Abfrageplan in der Google Cloud Console einsehen. Sie können Ausführungsdetails auch mit den INFORMATION_SCHEMA.JOBS*
-Ansichten oder der jobs.get
REST API-Methode anfordern.
Der Abfrageplan enthält Details zu Abfragephasen und -schritten. Mithilfe dieser Details können Sie Möglichkeiten zur Verbesserung der Abfrageleistung ermitteln. Beispiel: Wenn Sie eine Phase bemerken, in der viel mehr Ausgaben als in anderen Phasen geschrieben werden, bedeutet dies möglicherweise, dass Sie früher in der Abfrage filtern müssen.
Weitere Informationen zum Abfrageplan und Beispiele dafür, wie Sie mit den Informationen des Abfrageplans die Abfrageleistung verbessern können, finden Sie unter Statistiken zur Abfrageleistung abrufen. Nachdem Sie die Informationen zur Abfrageleistung behoben haben, können Sie die Abfrage weiter optimieren. Führen Sie dazu die folgenden Aufgaben aus:
- Zu verarbeitende Daten reduzieren
- Abfragevorgänge optimieren
- Ausgabe der Abfrage reduzieren
- BigQuery BI Engine-Reservierung verwenden
- Anti-SQL-Muster vermeiden
- Einschränkungen im Tabellenschema angeben
Verarbeitete Daten reduzieren
Mit den in den folgenden Abschnitten beschriebenen Optionen können Sie die zu verarbeitenden Daten reduzieren.
Auf SELECT *
verzichten
Best Practice: Sie können die Projektion steuern, indem Sie nur die benötigten Spalten abfragen.
Mit Projektion ist die Anzahl der Spalten gemeint, die bei der Abfrage gelesen werden. Durch das Projizieren unnötiger Spalten erhöhen sich der E/A-Umfang und die Schreibergebnisse.
- Verwenden Sie Datenvorschauoptionen. Wenn Sie mit Daten experimentieren oder Daten untersuchen, verwenden Sie anstelle von
SELECT *
eine der Datenvorschauoptionen. - Fragen Sie bestimmte Spalten ab. Mit einer
LIMIT
-Klausel in einerSELECT *
-Abfrage beeinflussen Sie nicht die Menge der gelesenen Daten. Ihnen werden immer alle in der gesamten Tabelle gelesenen Byte in Rechnung gestellt. Außerdem wird die Abfrage auf Ihr kostenloses Kontingent angerechnet. Fragen Sie stattdessen nur die Spalten ab, die Sie benötigen. Zum Beispiel verwenden SieSELECT * EXCEPT
, um eine oder mehrere Spalten aus den Ergebnissen auszuschließen. - Partitionierte Tabellen verwenden Wenn Sie alle Spalten einer Tabelle, aber nur eine Teilmenge der darin enthaltenen Daten abfragen möchten, haben Sie folgende Möglichkeiten:
- Die Ergebnisse in einer Zieltabelle erfassen und diese Tabelle abfragen.
- Tabellen partitionieren und die relevante Partition abfragen.
Verwenden Sie beispielsweise
WHERE _PARTITIONDATE="2017-01-01"
, um nur die Partition für den 1. Januar 2017 abzufragen.
Verwenden Sie
SELECT * EXCEPT
. Wenn Sie nur eine Teilmenge der Daten abfragen oder für die AbfrageSELECT * EXCEPT
verwenden, reduziert sich die von einer Abfrage gelesene Datenmenge in der Regel erheblich. Neben den Kosteneinsparungen profitieren Sie von der Leistungssteigerung, die Sie durch das Reduzieren des E/A-Umfangs und der Schreibergebnisse erreichen.SELECT * EXCEPT (col1, col2, col5) FROM mydataset.newtable
Platzhaltertabellen sparsam verwenden
Best Practice: Zum Abfragen von Platzhaltertabellen müssen Sie das genaueste Präfix verwenden.
Nutzen Sie Platzhalter, um mehrere Tabellen unter Verwendung kurzer SQL-Anweisungen abzufragen. Platzhaltertabellen stellen eine Zusammenführung aller Tabellen dar, die mit dem Platzhalterausdruck übereinstimmen. Sie sind nützlich, wenn Ihr Dataset die folgenden Ressourcen enthält:
- Mehrere Tabellen mit ähnlichen Namen und kompatiblen Schemas
- Fragmentierte Tabellen
Geben Sie zum Abfragen einer Platzhaltertabelle nach dem allgemeinen Tabellenpräfix einen Platzhalter (*
) ein. Mit FROM
werden beispielsweise alle Tabellen aus den 1940er-Jahren abgefragt.bigquery-public-data.noaa_gsod.gsod194*
Mit detailgenaueren Präfixen erzielen Sie bessere Ergebnisse als mit kurzen Präfixen. FROM
ist beispielsweise effizienter als bigquery-public-data.noaa_gsod.gsod194*
FROM
, da weniger Tabellen dem Platzhalter entsprechen.bigquery-public-data.noaa_gsod.*
Nach Datum fragmentierte Tabellen vermeiden
Best Practice: Verwenden Sie zeitpartitionierte Tabellen anstelle von Tabellen, die nach Datum fragmentiert sind (auch als datumsbenannte Tabellen bezeichnet).
Partitionierte Tabellen bieten eine bessere Leistung als datumsbenannte Tabellen. Wenn Sie nach Datum fragmentierte Tabellen verwenden, muss BigQuery für jede datumsbenannte Tabelle eine Kopie des Schemas und der Metadaten verwalten. Außerdem muss BigQuery möglicherweise für jede abgefragte datumsbenannte Tabelle die Berechtigungen überprüfen. Dieser Mehraufwand bei der Durchführung der Abfrage wirkt sich direkt auf die Abfrageleistung aus.
Übermäßige Tabellenfragmentierung vermeiden
Best Practice: Beschränken Sie die Anzahl von Tabellen-Shards. Wenn Sie Tabellen nach Datum fragmentieren, verwenden Sie stattdessen zeitpartitionierte Tabellen.
Bei der Fragmentierung werden große Datasets als eigene Tabellen abgetrennt und der Tabellenname erhält ein Suffix. Wenn Sie Tabellen nach Datum fragmentieren, verwenden Sie stattdessen zeitpartitionierte Tabellen.
Aufgrund der geringen Kosten für BigQuery-Speicher müssen Sie Ihre Tabellen nicht wie bei einem relationalen Datenbanksystem auf Kosten optimieren. Die Erstellung einer großen Anzahl von Tabellen-Shards hat Auswirkungen auf die Leistung, welche die etwaigen Kostenvorteile überwiegen.
Fragmentierte Tabellen benötigen BigQuery, um Schemas, Metadaten und Berechtigungen für jede Fragmentierung zu verwalten. Aufgrund des Mehraufwands, der zur Verwaltung der Informationen für jede Fragmentierung erforderlich ist, können zu viele Tabellenfragmentierungen die Abfrageleistung beeinträchtigen.
Die Menge und Quelle der von einer Abfrage gelesenen Daten kann sich auf die Abfrageleistung und die Kosten auswirken.
Partitionierte Abfragen bereinigen
Best Practice: Verwenden Sie beim Abfragen einer partitionierten Tabelle zum Filtern von Partitionen in partitionierten Tabellen die folgenden Spalten:
- Verwenden Sie für nach Aufnahmezeit partitionierte Tabellen die Pseudospalte
_PARTITIONTIME
. - Verwenden Sie für partitionierte Tabellen wie die nach Zeiteinheit spaltenbasierte und die des Ganzzahlbereichs die Partitionierungsspalte.
Bei nach Zeiteinheit partitionierten Tabellen können Sie durch Filtern der Daten mit _PARTITIONTIME
oder Partitionierungsspalten ein Datum oder einen Datumsbereich angeben. In der folgenden WHERE
-Klausel wird zum Beispiel die Pseudospalte _PARTITIONTIME
genutzt, um Partitionen zwischen dem 1. Januar 2016 und dem 31. Januar 2016 anzugeben:
WHERE _PARTITIONTIME
BETWEEN TIMESTAMP("20160101")
AND TIMESTAMP("20160131")
Die Abfrage verarbeitet nur Daten in den Partitionen, die durch den Zeitraum angegeben sind. Durch das Filtern der Partitionen verbessern Sie die Abfrageleistung und senken die Kosten.
Datenmenge vor einem JOIN
verkleinern
Best Practice: Verringern Sie die Menge der Daten, die vor einer JOIN
-Klausel verarbeitet werden, indem Sie Aggregationen durchführen.
Die Verwendung einer GROUP BY
-Klausel mit Aggregatfunktionen ist rechenintensiv, da diese Abfragetypen Shuffle verwenden.
Da diese Abfragen rechenintensiv sind, müssen Sie nur bei Bedarf eine GROUP BY
-Klausel verwenden.
Führen Sie für Abfragen mit GROUP BY
und JOIN
bereits in der Abfrage eine Aggregation durch, um die verarbeitete Datenmenge zu reduzieren.
Die folgende Abfrage führt beispielsweise ein JOIN
für zwei große Tabellen ohne vorherige Filterung aus:
WITH users_posts AS ( SELECT * FROM `bigquery-public-data`.stackoverflow.comments AS c JOIN `bigquery-public-data`.stackoverflow.users AS u ON c.user_id = u.id ) SELECT user_id, ANY_VALUE(display_name) AS display_name, ANY_VALUE(reputation) AS reputation, COUNT(text) AS comments_count FROM users_posts GROUP BY user_id ORDER BY comments_count DESC LIMIT 20;
Bei dieser Abfrage wird die Anzahl der Kommentare vorab zusammengefasst, wodurch die Menge der gelesenen Daten für JOIN
reduziert wird:
WITH comments AS ( SELECT user_id, COUNT(text) AS comments_count FROM `bigquery-public-data`.stackoverflow.comments WHERE user_id IS NOT NULL GROUP BY user_id ORDER BY comments_count DESC LIMIT 20 ) SELECT user_id, display_name, reputation, comments_count FROM comments JOIN `bigquery-public-data`.stackoverflow.users AS u ON user_id = u.id ORDER BY comments_count DESC;
WHERE
-Klausel verwenden
Best Practice: Verwenden Sie eine WHERE
-Klausel, um die von einer Abfrage zurückgegebene Datenmenge zu begrenzen. Verwenden Sie nach Möglichkeit die Spalten BOOL
, INT
, FLOAT
oder DATE
in der WHERE
-Klausel.
Vorgänge für die Spalten BOOL
, INT
, FLOAT
und DATE
sind in der Regel schneller als Vorgänge für die Spalten STRING
oder BYTE
. Verwenden Sie nach Möglichkeit eine Spalte, die einen dieser Datentypen in der WHERE
-Klausel verwendet, um die von der Abfrage zurückgegebene Datenmenge zu reduzieren.
Abfragevorgänge optimieren
Sie können Ihre Abfragevorgänge mit den in den folgenden Abschnitten beschriebenen Optionen optimieren.
Wiederholtes Transformieren von Daten vermeiden
Best Practice: Vermeiden Sie beim Verwenden von SQL für ETL-Vorgänge Situationen, in denen Sie wiederholt die gleichen Daten transformieren.
Wenn Sie zum Beispiel SQL verwenden, um mit regulären Ausdrücken Strings zu verkürzen oder Daten zu extrahieren, ist es sinnvoller, die transformierten Ergebnisse in einer Zieltabelle zu erfassen. Funktionen wie reguläre Ausdrücke erfordern zusätzlichen Rechenaufwand. Das Abfragen der Zieltabelle ohne den zusätzlichen Transformationsaufwand ist viel effizienter.
Mehrere Auswertungen derselben CTEs vermeiden
Best Practice: Verwenden Sie die prozedurale Sprache, Variablen, temporäre Tabellen und automatisch ablaufende Tabellen, um Berechnungen zu speichern und sie später in der Abfrage zu verwenden.
Wenn Ihre Abfrage allgemeine Tabellenausdrücke (CTEs) enthält, die an mehreren Stellen in der Abfrage verwendet werden, werden sie möglicherweise jedes Mal ausgewertet, wenn sie referenziert werden. Die Abfrageoptimierung versucht, Teile der Abfrage zu erkennen, die nur einmal ausgeführt werden können. Dies ist jedoch nicht immer möglich. Daher kann die Verwendung eines CTE die interne Abfragekomplexität und den Ressourcenverbrauch möglicherweise nicht reduzieren.
Sie können das Ergebnis einer CTE in einer skalaren Variable oder einer temporären Tabelle speichern, abhängig von den Daten, die die CTE zurückgibt.
Wiederholte Joins und Unterabfragen vermeiden
Best Practice: Vermeiden Sie wiederholte Joins derselben Tabellen sowie die Verwendung derselben Unterabfragen.
Anstatt Daten wiederholt zu verknüpfen, können Sie Beziehungen vielleicht durch verschachtelte wiederkehrende Daten darstellen und dadurch die Leistung steigern. Mithilfe verschachtelter wiederkehrender Daten lassen sich die Leistungseinbußen vermeiden, die durch die zusätzliche Datenübertragung bei der Verwendung von Joins entstehen. Außerdem sparen Sie sich die E/A-Kosten, die durch das wiederholte Lesen und Schreiben derselben Daten verursacht werden. Weitere Informationen finden Sie unter Verschachtelte und wiederkehrende Felder verwenden.
Auch die Verwendung der immer gleichen Unterabfragen wirkt sich aufgrund der sich wiederholenden Abfrageverarbeitung negativ auf die Leistung aus. Wenn Sie dieselben Unterabfragen in mehreren Abfragen verwenden, empfiehlt es sich, die Ergebnisse der Unterabfrage in einer Tabelle zu materialisieren. Auf diese Weise können Sie in den Abfragen einfach die Tabellendaten verwenden.
Die Materialisierung der Abfrageergebnisse verbessert die Leistung und verringert die Gesamtmenge an Daten, die von BigQuery gelesen und geschrieben werden muss. Die geringen Kosten für die Speicherung der materialisierten Daten sind leichter zu verkraften als die Auswirkung einer wiederholten E/A- und Abfrageverarbeitung auf die Leistung.
Join-Muster optimieren
Best Practice: Optimieren Sie Ihre Join-Muster für Abfragen, die Daten aus mehreren Tabellen miteinander verbinden, indem Sie mit der größten Tabelle beginnen.
Berücksichtigen Sie beim Erstellen einer Abfrage mit einer JOIN
-Klausel die Reihenfolge, in der Sie die Daten zusammenführen. Das Tool zur Optimierung von GoogleSQL-Abfragen legt fest, welche Tabelle auf welcher Seite der Verknüpfung stehen sollte. Als Best Practice sollten Sie die Tabelle mit der größten Anzahl an Zeilen zuerst platzieren, gefolgt von der Tabelle mit den wenigsten Zeilen und die übrigen Tabellen nach unten ordnen.
Wenn eine große Tabelle links von JOIN
und eine kleine rechts von JOIN
steht, wird ein Broadcast-Join erstellt. Dabei werden alle Daten in der kleineren Tabelle an die Slots gesendet, die die größere Tabelle verarbeiten. Sie sollten den Broadcast-Join zuerst ausführen.
Informationen zur Anzeige der Tabellengröße in Ihrem JOIN
finden Sie unter Informationen zu Tabellen abrufen.
ORDER BY
-Klausel optimieren
Best Practice: Folgen Sie bei der Verwendung der Klausel ORDER BY
den Best Practices:
Verwenden Sie
ORDER BY
in der äußersten Abfrage oder innerhalb von Fensterklauseln. Verschieben Sie komplexe Operationen an das Ende der Abfrage. In der Mitte einer Abfrage führt dieORDER BY
-Klausel zu einer erheblichen Leistungsbeeinträchtigung, wenn sie nicht in einer Fensterfunktion verwendet wird.Eine weitere Methode zum Sortieren einer Abfrage besteht darin, komplexe Vorgänge wie reguläre Ausdrücke und mathematische Funktionen an das Ende zu stellen. Diese Technik reduziert die zu verarbeitenden Daten, bevor die komplexen Vorgänge ausgeführt werden.
Verwenden Sie eine
LIMIT
-Klausel. Verwenden Sie eineLIMIT
-Klausel, wenn Sie eine sehr große Anzahl an Werten bestellen, aber nicht alle zurückgeben müssen. Die folgende Abfrage ordnet beispielsweise eine sehr große Ergebnismenge an und gibt den FehlerResources exceeded
zurück. Die Abfrage sortiert die Spaltetitle
inmytable
. Die Spaltetitle
enthält mehrere Millionen Werte.SELECT title FROM `my-project.mydataset.mytable` ORDER BY title;
Damit der Fehler nicht auftritt, formulieren Sie die Abfrage so:
SELECT title FROM `my-project.mydataset.mytable` ORDER BY title DESC LIMIT 1000;
Verwenden Sie eine Fensterfunktion. Wenn Sie eine sehr große Anzahl an Werten bestellen, sollten Sie eine Fensterfunktion verwenden und die Daten vor dem Aufrufen der Fensterfunktion einschränken. Die folgende Abfrage listet z. B. die zehn ältesten Stack Overflow-Nutzer und deren Ranking auf, wobei das älteste Konto am niedrigsten eingestuft wird:
SELECT id, reputation, creation_date, DENSE_RANK() OVER (ORDER BY creation_date) AS user_rank FROM bigquery-public-data.stackoverflow.users ORDER BY user_rank ASC LIMIT 10;
Diese Abfrage dauert ca.15 Sekunden. Diese Abfrage verwendet
LIMIT
am Ende der Abfrage, jedoch nicht in der FensterfunktionDENSE_RANK() OVER
. Aus diesem Grund müssen für die Abfrage alle Daten auf einen Worker-Knoten sortiert werden.Stattdessen sollten Sie das Dataset vor der Berechnung der Fensterfunktion einschränken, um die Leistung zu verbessern:
WITH users AS ( SELECT id, reputation, creation_date, FROM bigquery-public-data.stackoverflow.users ORDER BY creation_date ASC LIMIT 10) SELECT id, reputation, creation_date, DENSE_RANK() OVER (ORDER BY creation_date) AS user_rank FROM users ORDER BY user_rank;
Diese Abfrage dauert ungefähr zwei Sekunden. Dabei werden dieselben Ergebnisse wie bei der vorherigen Abfrage zurückgegeben.
Ein Nachteil ist, dass die Funktion
DENSE_RANK()
die Daten innerhalb von Jahren sortiert. Daher liefern diese Abfragen bei Rankingdaten, die sich über mehrere Jahre erstrecken, keine identischen Ergebnisse.
Komplexe Abfragen in kleinere aufteilen
Best Practice: Nutzen Sie Abfragen mit mehreren Anweisungen und gespeicherte Prozeduren, um Berechnungen, die als eine komplexe Abfrage konzipiert waren, stattdessen als mehrere kleinere und einfachere Abfragen durchzuführen.
Komplexe Abfragen, REGEX
-Funktionen und mehrschichtige Unterabfragen oder Joins können langsam und ressourcenintensiv sein. Der Versuch, alle Berechnungen in eine große SELECT
-Anweisung aufzunehmen, z. B. zur Ansicht, ist manchmal ein Antimuster und kann zu einer langsamen, ressourcenintensiven Abfrage führen. In extremen Fällen wird der interne Abfrageplan so komplex, dass BigQuery ihn nicht ausführen kann.
Das Aufteilen einer komplexen Abfrage ermöglicht die Materialisierung von Zwischenergebnissen in Variablen oder temporären Tabellen. Sie können diese Zwischenergebnisse dann in anderen Teilen der Abfrage verwenden. Es ist immer nützlicher, wenn diese Ergebnisse an mehreren Stellen der Abfrage benötigt werden.
Häufig können Sie den tatsächlichen Intent von Teilen der Abfrage besser ausdrücken, indem Sie temporäre Tabellen als Punkte der Datenmaterialisierung verwenden.
Verschachtelte und wiederkehrende Felder verwenden
Informationen zum Denormalisieren der Datenspeicherung mithilfe verschachtelter und wiederkehrender Felder finden Sie unter Verschachtelte und wiederkehrende Felder verwenden.
INT64
-Datentypen in Joins verwenden
Best Practice: Verwenden Sie INT64
-Datentypen in Joins anstelle von STRING
-Datentypen, um die Kosten zu senken und die Vergleichsleistung zu verbessern.
BigQuery indexiert keine Primärschlüssel wie herkömmliche Datenbanken. Je größer daher die Join-Spalte ist, desto länger dauert der Vergleich. Deshalb ist die Verwendung von INT64
-Datentypen in Joins günstiger und effizienter als die Verwendung von STRING
-Datentypen.
Ausgabe von Abfragen reduzieren
Sie können die Abfrageausgaben reduzieren, indem Sie die in den folgenden Abschnitten beschriebenen Optionen verwenden.
Große Ergebnismengen erfassen
Best Practice: Überlegen Sie, ob Sie eine Materialisierung umfangreicher Ergebnismengen in einer Zieltabelle durchführen möchten. Das Schreiben großer Ergebnismengen wirkt sich sowohl auf die Leistung als auch auf die Kosten aus.
BigQuery begrenzt die im Cache gespeicherten Ergebnisse auf ca. 10 GB in komprimierter Form. Abfragen, die größere Ergebnismengen zurückgeben, überschreiten dieses Limit, was häufig zu folgendem Fehler führt: Response too large
.
Dieser Fehler tritt auf, wenn aus einer Tabelle, die eine große Datenmenge enthält, eine große Zahl von Feldern ausgewählt wird. Probleme beim Schreiben von zwischengespeicherten Ergebnissen können auch bei ETL-ähnlichen Abfragen auftreten, bei denen Daten ohne Verkleinerung oder Zusammenfassung normalisiert werden.
Mit den folgenden Optionen können Sie die Größenbeschränkung von zwischengespeicherten Ergebnissen umgehen:
- Schränken Sie die Ergebnismenge mithilfe von Filtern ein.
- Verkleinern Sie die Ergebnismenge mithilfe einer
LIMIT
-Klausel, insbesondere wenn Sie auch eineORDER BY
-Klausel verwenden. - Schreiben Sie die Ausgabedaten in eine Zieltabelle.
Sie können mit der BigQuery REST API in den Ergebnissen suchen. Weitere Informationen finden Sie unter In Tabellendaten suchen.
BI Engine verwenden
Um Ihre SQL-Abfragen weiter zu beschleunigen, indem Sie die am häufigsten verwendeten Daten im Cache speichern, sollten Sie dem Projekt, in dem die Abfragen berechnet werden, eine BI Engine-Reservierung hinzufügen.
BigQuery BI Engine verwendet eine vektorisierte Abfrage-Engine, um die SELECT
-Abfrageleistung zu beschleunigen.
Anti-SQL-Muster vermeiden
Die folgenden Best Practices enthalten Informationen darüber, wie Sie nachteilige Designmuster in Abfragen, die die Leistung von BigQuery beeinträchtigen, vermeiden können.
Self Joins vermeiden
Best Practice: Nutzen Sie statt Self Joins eine (analytische) Fensterfunktion oder den PIVOT
-Operator.
Self Joins werden üblicherweise eingesetzt, um zeilenabhängige Beziehungen zu berechnen. Dies kann jedoch dazu führen, dass sich die Zahl der Ausgabezeilen quadriert, was wiederum die Leistung beeinträchtigen kann.
Cross Joins vermeiden
Best Practice: Vermeiden Sie Joins, die mehr Ausgaben als Eingaben erzeugen. Fassen Sie Ihre Daten für CROSS JOIN
vorab zusammen.
Cross Joins sind Abfragen, bei denen jede Zeile aus der ersten Tabelle mit jeder Zeile in der zweiten Tabelle verknüpft ist. (Auf beiden Seiten gibt es nicht eindeutige Schlüssel.) Im schlimmsten Fall ist die Ausgabe die Zahl der Zeilen in der linken Tabelle multipliziert mit der Zahl der Zeilen in der rechten Tabelle. In extremen Fällen kann die Abfrage nicht beendet werden.
Wenn die Abfrage abgeschlossen ist, zeigt die Abfrageplanerläuterung einen Vergleich der Ausgabe- und Eingabezeilen. Sie können überprüfen, ob es sich um ein kartesisches Produkt handelt, indem Sie die Abfrage so ändern, dass die Anzahl der Zeilen auf jeder Seite der JOIN
-Klausel ausgegeben wird, gruppiert nach JOIN-Schlüssel.
So vermeiden Sie Leistungsprobleme aufgrund von Verknüpfungen, die mehr Ausgaben als Eingaben generieren:
- Verwenden Sie eine
GROUP BY
-Klausel, um die Daten vorab zusammenzufassen. - Verwenden Sie eine Fensterfunktion. Diese ist häufig effizienter als ein Cross Join. Weitere Informationen finden Sie unter Fensterfunktionen.
DML-Anweisungen, die einzelne Zeilen aktualisieren oder einfügen, vermeiden
Best Practice: Vermeiden Sie DML, die einzelne Zeilen aktualisieren oder einfügen. Verarbeiten Sie stattdessen Updates und Einfügungen stapelweise.
Mit punktspezifischen DML-Anweisungen soll BigQuery wie ein OLTP-System (Online Transaction Processing) eingesetzt werden. BigQuery konzentriert sich aber auf OLAP (Online Analytical Processing) anhand von Tabellenscans anstatt von Punktabrufen. Wenn Sie OLTP-ähnliche Prozesse durchführen möchten (Aktualisieren oder Einfügen einzelner Zeilen), sollten Sie eine Datenbank verwenden, die OLTP-Anwendungsfälle unterstützt, etwa Cloud SQL.
BigQuery-DML-Anweisungen eignen sich für Sammelaktualisierungen. Die DML-Anweisungen UPDATE
und DELETE
in BigQuery können Sie verwenden, um Ihre Daten regelmäßig neu zu schreiben, nicht aber für Mutationen einzelner Zeilen. Die DML-Anweisung INSERT
sollten Sie sparsam einsetzen. Für Einfügungen gelten dieselben Änderungskontingente wie für Ladejobs. Wenn Ihr Anwendungsfall das häufige Einfügen einzelner Zeilen umfasst, sollten Sie stattdessen Ihre Daten streamen.
Wenn die Stapelverarbeitung Ihrer UPDATE
-Anweisungen viele Tupel in sehr langen Abfragen liefert, können diese die Längenbeschränkung von 256 KB erreichen. Zum Umgehen dieser Beschränkung sollten Sie prüfen, ob die Aktualisierungen auf der Grundlage eines logischen Kriteriums statt einer Reihe direkter Tupelersetzungen durchgeführt werden können.
Sie können beispielsweise die Ersatzdatensätze in eine andere Tabelle laden und dann eine DML-Anweisung zum Aktualisieren aller Werte in der ursprünglichen Tabelle schreiben, wenn die nicht aktualisierten Spalten übereinstimmen. Im folgenden Beispiel befinden sich die ursprünglichen Daten in Tabelle t
und die Aktualisierungen in Tabelle u
. Die Abfrage sieht dann so aus:
UPDATE dataset.t t SET my_column = u.my_column FROM dataset.u u WHERE t.my_key = u.my_key
Aliasnamen für ähnlich benannte Spalten verwenden
Best Practice: Verwenden Sie Spalten- und Tabellenaliasse, wenn Sie in allen Abfragen, einschließlich Unterabfragen, mit ähnlich benannten Spalten arbeiten.
Mit Aliassen können Sie ermitteln, auf welche Spalten und Tabellen zusätzlich zu Ihrer anfänglichen Referenz auf die Spalte verwiesen wird. Die Verwendung von Aliassen kann Ihnen helfen, Probleme in Ihrer SQL-Abfrage zu verstehen und zu beheben, einschließlich der Suche nach Spalten, die in Unterabfragen verwendet werden.
Einschränkungen im Tabellenschema angeben
Wenn Tabellendaten Einschränkungen enthalten, geben Sie die Einschränkungen im Tabellenschema an. Die Abfrage-Engine kann Abfragepläne mithilfe von Tabelleneinschränkungen optimieren.
Beschränkungen für Primärschlüssel und Fremdschlüssel angeben
Sie sollten Schlüsseleinschränkungen im Tabellenschema angeben, wenn Tabellendaten die Anforderungen an die Datenintegrität von Primärschlüssel- oder Fremdschlüsseleinschränkungen erfüllen. Die Abfrage-Engine kann die Schlüsseleinschränkungen verwenden, um Abfragepläne zu optimieren. Ausführliche Informationen finden Sie im Blogpost Join optimizations with BigQuery primary keys and foreign keys.
BigQuery prüft die Datenintegrität nicht automatisch. Sie müssen daher darauf achten, dass Ihre Daten den im Tabellenschema angegebenen Einschränkungen entsprechen. Wenn Sie die Datenintegrität in Tabellen mit bestimmten Einschränkungen nicht aufrechterhalten, sind Ihre Abfrageergebnisse möglicherweise ungenau.