Die partitionierte Datenbearbeitungssprache (Partitioned Data Manipulation Language, DML) wurde für die folgenden Arten von Bulk-Aktualisierungen und -Löschvorgängen entwickelt:
- Regelmäßige und automatische Speicherbereinigungsvorgänge. Beispiele: Alte Zeilen löschen oder Spalten auf
NULL
setzen. - Backfilling neuer Spalten mit Standardwerten. Beispiel: Mit einer
UPDATE
-Anweisung können Sie für den Wert einer neuen SpalteFalse
festlegen, für die aktuellNULL
gilt.
Partitionierte DML eignet sich nicht für die Verarbeitung kleiner Transaktionen. Wenn Sie eine Anweisung für einige Zeilen ausführen möchten, verwenden Sie transaktionale DMLs mit identifizierbaren Primärschlüsseln. Weitere Informationen finden Sie unter DML verwenden.
Wenn Sie eine große Anzahl von Blindschreibvorgängen ausführen, aber keine atomare Transaktion benötigen, können Sie Ihre Spanner-Tabellen mithilfe von Batch-Schreiben im Bulk-Verfahren ändern. Weitere Informationen finden Sie unter Daten mit Batch-Schreiben ändern.
In Statistiktabellen in Ihrer Spanner-Datenbank finden Sie Statistiken zu aktiven partitionierten DML-Abfragen und deren Fortschritt. Weitere Informationen finden Sie unter Statistiken zu aktiven partitionierten DMLs.
DML und partitionierte DML
Spanner unterstützt zwei Ausführungsmodi für DML-Anweisungen:
DML, die für die Transaktionsverarbeitung geeignet ist. Weitere Informationen finden Sie unter DML verwenden.
Partitionierte DML ermöglicht umfangreiche, datenbankweite Vorgänge mit minimaler Auswirkung auf die gleichzeitige Transaktionsverarbeitung. Bei diesen Vorgängen wird der Schlüsselbereich partitioniert und die Anweisung wird in separaten, weniger umfangreichen Transaktionen auf die Partitionen angewendet. Weitere Informationen finden Sie unter Partitionierte DML verwenden.
Die folgende Tabelle zeigt einen Vergleich der beiden Ausführungsmodi.
DML | Partitionierte DML |
---|---|
Zeilen, die nicht mit der WHERE -Klausel übereinstimmen, können gesperrt werden. |
Nur Zeilen, die mit der WHERE -Klausel übereinstimmen, werden gesperrt. |
Die Transaktionsgröße ist begrenzt. | Spanner unterstützt alle Transaktionsgrößen und gleichzeitig ausgeführten Transaktionen. |
Anweisungen müssen nicht idempotent sein. | DML-Anweisungen müssen idempotent sein, um konsistente Ergebnisse zu gewährleisten. |
Transaktionen können mehrere DML- und SQL-Anweisungen enthalten. | Partitionierte Transaktionen können nur eine DML-Anweisung enthalten. |
Es gibt keine Einschränkungen hinsichtlich der Komplexität von Anweisungen. | Anweisungen müssen vollständig partitionierbar sein. |
Sie erstellen Lese- und Schreibtransaktionen im Clientcode. | Spanner erstellt die Transaktionen. |
Partitionierbar und idempotent
Bei der Ausführung partitionierter DML-Anweisungen haben die Zeilen in einer Partition keinen Zugriff auf die Zeilen in anderen Partitionen. Sie selbst haben keinen Einfluss darauf, wie Spanner die Partitionen erstellt. Partitionierung gewährleistet Skalierbarkeit, setzt jedoch voraus, dass partitionierte DML-Anweisungen vollständig partitionierbar sind. Das heißt, es muss möglich sein, die partitionierte DML-Anweisung als Vereinigung mehrerer Anweisungen auszudrücken, wobei jede Anweisung auf genau eine Zeile der Tabelle und keine anderen Tabellen zugreift. So sind beispielsweise DML-Anweisungen, die auf mehrere Tabellen zugreifen oder sich selbst verknüpfen (self-join), nicht partitionierbar. Wenn die DML-Anweisung nicht partitionierbar ist, gibt Spanner den Fehler BadUsage
zurück.
Diese DML-Anweisungen sind vollständig partitionierbar, da jede Anweisung auf genau eine Zeile in der Tabelle angewendet werden kann:
UPDATE Singers SET LastName = NULL WHERE LastName = '';
DELETE FROM Albums WHERE MarketingBudget > 10000;
Diese DML-Anweisung kann nicht vollständig partitioniert werden, da sie auf mehrere Tabellen zugreift:
# Not fully partitionable
DELETE FROM Singers WHERE
SingerId NOT IN (SELECT SingerId FROM Concerts);
Es kann vorkommen, dass Spanner partitionierte DML-Anweisungen aufgrund von Wiederholungen auf Netzwerkebene für einige Partitionen mehrmals ausführt. Dadurch wird eine Anweisung für eine Zeile möglicherweise mehrmals ausgeführt. Die Anweisung muss daher idempotent sein, um konsistente Ergebnisse zu erzielen. Anweisungen sind idempotent, wenn die mehrfache Ausführung für eine Zeile immer zum selben Ergebnis führt.
Diese DML-Anweisung ist idempotent:
UPDATE Singers SET MarketingBudget = 1000 WHERE true;
Diese DML-Anweisung ist nicht idempotent:
UPDATE Singers SET MarketingBudget = 1.5 * MarketingBudget WHERE true;
Zeilensperre
Spanner erwirbt Sperren nur für Zeilen, die Kandidaten für Aktualisierungs- oder Löschvorgänge sind. Dieses Verhalten unterscheidet sich von der DML-Ausführung. Hier können auch Zeilen, die nicht mit der WHERE
-Klausel übereinstimmen, eine Lesesperre erhalten.
Ausführung und Transaktionen
Ob eine DML-Anweisung partitioniert ist oder nicht, hängt von der Clientbibliotheksmethode ab, die Sie für die Ausführung auswählen. Jede Clientbibliothek stellt für die DML-Ausführung und die partitionierte DML-Ausführung separate Methoden bereit.
Pro Aufruf der Clientbibliotheksmethode können Sie nur eine partitionierte DML-Anweisung ausführen.
Spanner wendet partitionierte DML-Anweisungen nicht atomar auf die gesamte Tabelle an. Auf die einzelnen Partitionen werden sie jedoch atomisch angewendet.
Partitionierte DML-Anweisungen unterstützen kein Commit oder Rollback. Spanner führt die DML-Anweisung sofort aus und wendet sie an.
- Wenn Sie den Vorgang abbrechen, bricht Spanner die ausgeführten Partitionen ab und startet die verbleibenden Partitionen nicht. Spanner führt für bereits ausgeführte Partitionen kein Rollback aus.
- Wenn die Ausführung der Anweisung einen Fehler verursacht, wird die Ausführung in allen Partitionen beendet und Spanner gibt den Fehler für den gesamten Vorgang zurück. Fehler werden beispielsweise bei Verstößen gegen Datentypeinschränkungen, gegen
UNIQUE INDEX
und gegenON DELETE NO ACTION
ausgelöst. Je nachdem, an welchem Punkt der Ausführung der Fehler auftritt, ist die Anweisung möglicherweise für einige Partitionen erfolgreich und für andere aber nicht.
Bei einer erfolgreichen Ausführung wurde die partitionierte DML-Anweisung von Spanner für jede Partition des Schlüsselbereichs mindestens einmal ausgeführt.
Anzahl geänderter Zeilen
Eine partitionierte DML-Anweisung gibt die Zahl der Zeilen aus, die mindestens geändert wurden. Diese Zahl muss nicht exakt sein. Es gibt keine Garantie dafür, dass Spanner alle geänderten Zeilen gezählt hat.
Transaktionslimits
Spanner erstellt die Partitionen und Transaktionen, die zum Ausführen einer partitionierten DML-Anweisung erforderlich sind. Es gelten Transaktionslimits und Gleichzeitigkeitslimits pro Transaktion. Spanner versucht, die Transaktionen innerhalb dieser Limits zu halten.
Spanner unterstützt pro Datenbank maximal 20.000 partitionierte DML-Anweisungen gleichzeitig.
Nicht unterstützte Funktionen
Die folgenden Features für partitionierte DML-Anweisungen werden von Spanner nicht unterstützt:
INSERT
wird nicht unterstützt.- Google Cloud Console: Partitionierte DML-Anweisungen können in der Google Cloud Console nicht ausgeführt werden.
- Abfragepläne und Profilerstellung: Die Google Cloud CLI und die Clientbibliotheken unterstützen keine Abfragepläne und keine Profilerstellung.
- Unterabfragen, die Daten aus einer anderen Tabelle oder einer anderen Zeile derselben Tabelle lesen.
Für komplexe Szenarien wie das Verschieben einer Tabelle oder Transformationen, die Joins zwischen Tabellen erfordern, sollten Sie den Dataflow-Connector verwenden.
Beispiele
Mit den folgenden Codebeispielen wird die Spalte MarketingBudget
der Tabelle Albums
aktualisiert.
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie die Funktion ExecutePartitionedDml()
.
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie die Methode ExecutePartitionedUpdateAsync()
.
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie die Methode PartitionedUpdate()
.
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie die Methode executePartitionedUpdate()
.
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie die Methode runPartitionedUpdate()
.
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie die Methode executePartitionedUpdate()
.
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie die Methode execute_partitioned_dml()
.
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie die Methode execute_partitioned_update()
.
Im folgenden Codebeispiel werden Zeilen aus der Tabelle Singers
anhand der Spalte SingerId
gelöscht.
Nächste Schritte
Erfahren Sie, wie Sie Daten mit DML ändern.
Informationen zu den Best Practices für die Datenbearbeitungssprache (DML).
Weitere Informationen zu den Unterschieden zwischen DML und Mutationen finden Sie unter DML und Mutationen vergleichen.
Für andere Datentransformationsszenarien können Sie den Dataflow-Connector verwenden.