Auf dieser Seite werden die Best Practices für die Verwendung der Datenbearbeitungssprache (Data Manipulation Language – DML) und der partitionierten DML beschrieben.
Mit einer WHERE-Klausel die Anzahl der gesperrten Zeilen reduzieren
Sie führen DML-Anweisungen in Lese- und Schreibtransaktionen aus. Wenn Spanner Daten liest,
erhält gemeinsam genutzte Lesesperren für begrenzte Teile der von Ihnen gelesenen Zeilenbereiche. Insbesondere werden diese Sperren nur für die Spalten übernommen, auf die Sie zugreifen. Die Sperren können Daten enthalten,
die Filterbedingung der WHERE
-Klausel erfüllen.
Wenn Spanner Daten mit DML-Anweisungen ändert, werden exklusive Sperren für die die Sie ändern. Darüber hinaus werden gemeinsame Sperren auf die gleiche Weise wie beim Lesen von Daten angewendet. Wenn Ihre Anfrage große Zeilenbereiche oder eine ganze Tabelle umfasst, Sperren können verhindern, dass andere Transaktionen parallel verarbeitet werden.
Um Daten so effizient wie möglich zu ändern, verwenden Sie eine WHERE
-Klausel, mit der Spanner nur die erforderlichen Zeilen liest. Sie können dafür einen Filter für den Primärschlüssel oder für den Schlüssel eines Sekundärindex nutzen. Die Klausel WHERE
beschränkt den Umfang der gemeinsamen Sperren und ermöglicht es Spanner, die Aktualisierung effizienter zu verarbeiten.
Angenommen, einer der Musiker in der Tabelle Singers
ändert seinen Vornamen und Sie müssen den Namen in Ihrer Datenbank aktualisieren. Sie können dafür die im Folgenden dargestellte DML-Anweisung ausführen. Diese führt aber dazu, dass Spanner die komplette Tabelle prüft und gemeinsame Sperren übernimmt, die die komplette Tabelle betreffen. Spanner muss dann mehr Daten als erforderlich lesen und gleichzeitige Transaktionen können die Daten nicht parallel ändern:
-- ANTI-PATTERN: SENDING AN UPDATE WITHOUT THE PRIMARY KEY COLUMN
-- IN THE WHERE CLAUSE
UPDATE Singers SET FirstName = "Marcel"
WHERE FirstName = "Marc" AND LastName = "Richards";
Für eine effizientere Aktualisierung nehmen Sie die Spalte SingerId
in die WHERE
-Klausel auf. Die Spalte SingerId
ist die einzige primäre Schlüsselspalte für die Tabelle Singers
:
-- ANTI-PATTERN: SENDING AN UPDATE THAT MUST SCAN THE ENTIRE TABLE
UPDATE Singers SET FirstName = "Marcel"
WHERE FirstName = "Marc" AND LastName = "Richards"
Wenn es keinen Index für FirstName
oder LastName
gibt, müssen Sie die gesamte Tabelle scannen, um die gewünschten Sänger zu finden. Wenn Sie keinen sekundären Index hinzufügen möchten, um die Aktualisierung effizienter zu gestalten, nehmen Sie die Spalte SingerId
in die WHERE
-Klausel auf.
Die Spalte SingerId
ist die einzige Primärschlüsselspalte für die Tabelle Singers
. Führen Sie dazu SELECT
in einer separaten schreibgeschützten Transaktion vor der Aktualisierungstransaktion aus:
SELECT SingerId
FROM Singers
WHERE FirstName = "Marc" AND LastName = "Richards"
-- Recommended: Including a seekable filter in the where clause
UPDATE Singers SET FirstName = "Marcel"
WHERE SingerId = 1;
DML-Anweisungen und Mutationen nicht in derselben Transaktion verwenden
Spanner speichert Einfügungen, Aktualisierungen und Löschungen, die mit DML-Anweisungen auf der Serverseite durchgeführt wurden, im Zwischenspeicher. Die Ergebnisse sind für nachfolgende SQL- und DML-Anweisungen in derselben Transaktion sichtbar. Dieses Verhalten unterscheidet sich von der Mutation API, bei der Spanner die Mutationen auf der Clientseite zwischenspeichert und sie serverseitig als Teil des Commit-Vorgangs sendet. Folglich sind Mutationen in der Commit-Anfrage für SQL- oder DML-Anweisungen in derselben Transaktion nicht sichtbar.
Vermeiden Sie die Verwendung von DML-Anweisungen und Mutationen in derselben Transaktion. Wenn Sie beide in derselben Transaktion verwenden, müssen Sie die Reihenfolge der Ausführung in Ihrem Client-Bibliothekscode berücksichtigen. Wenn eine Transaktion sowohl DML enthält Anweisungen und Mutationen in derselben Anfrage ausführen, führt Spanner DML-Anweisungen vor den Mutationen.
Bei Vorgängen, die nur mithilfe von Mutationen unterstützt werden, können Sie DML-Anweisungen und Mutationen in derselben Transaktion kombinieren, z. B. insert_or_update
.
Wenn Sie beide verwenden, werden die Daten nur am Ende der Transaktion in den Puffer geschrieben.
Mit der Funktion PENDING_COMMIT_TIMESTAMP um Commit-Zeitstempel schreiben
GoogleSQL
Schreiben Sie mit der Funktion PENDING_COMMIT_TIMESTAMP
den Commit-Zeitstempel in eine DML-Anweisung. Spanner wählt den Commit-Zeitstempel aus, wenn der Commit der Transaktion ausgeführt wird.
PostgreSQL
Schreiben Sie mit der Funktion SPANNER.PENDING_COMMIT_TIMESTAMP()
den Commit-Zeitstempel in eine DML-Anweisung. Spanner wählt den Commit-Zeitstempel aus, wenn die Transaktion
Commits übergeben.
Partitionierte DML-, Datums- und Zeitstempelfunktionen
Partitionierte DML verwendet eine oder mehrere Transaktionen, die möglicherweise zu unterschiedlichen Zeitpunkten ausgeführt und bereitgestellt werden. Wenn Sie die Datums- oder Zeitstempelfunktion verwenden, können die geänderten Zeilen andere Werte enthalten.
Latenz mit Batch-DML verbessern
Verwenden Sie Batch-DML, um mehrere DML-Anweisungen innerhalb einer einzigen Client-zu-Server-Weiterleitung an Spanner zu senden, um die Latenz zu reduzieren.
Batch-DML kann Optimierungen auf Gruppen von Anweisungen in um Daten schneller und effizienter aktualisieren zu können.
Schreibvorgänge mit einer einzigen Anfrage ausführen
Spanner optimiert automatisch zusammenhängende Gruppen ähnlicher INSERT-, UPDATE- oder DELETE-Batchanweisungen mit unterschiedlichen Parameterwerten, sofern sie nicht gegen Datenabhängigkeiten verstoßen.
Angenommen, Sie möchten eine große Anzahl neuer Zeilen in eine Tabelle namens
Albums
einfügen. Damit Spanner alleINSERT
-Anweisungen in einer einzigen, effizienten serverseitigen Aktion kombiniert. beginnen Sie mit dem Schreiben einer entsprechenden DML-Anweisung, die SQL-Abfrage Parameter:INSERT INTO Albums (SingerId, AlbumId, AlbumTitle) VALUES (@Singer, @Album, @Title);
Senden Sie dann einen DML-Batch an Spanner, der diese Anweisung aufruft. wiederholt und zusammenhängend, wobei sich die Wiederholungen nur in der -Werte, die Sie an die drei Abfrageparameter der Anweisung binden. Spanner optimiert diese strukturell identischen DML-Anweisungen zu einem einzigen serverseitigen Vorgang, bevor sie ausgeführt werden.
Schreibvorgänge parallel ausführen
Spanner optimiert automatisch zusammenhängende Gruppen von DML-Anweisungen, indem sie parallel ausgeführt werden, sofern dies nicht gegen Datenabhängigkeiten verstößt. Diese Optimierung bietet Leistungsvorteile für eine größere Anzahl von DML-Batchanweisungen, da sie sowohl auf eine Mischung von DML-Anweisungstypen (INSERT, UPDATE und DELETE) als auch auf parametrisierte und nicht parametrisierte DML-Anweisungen angewendet werden kann.
Unser Beispielschema enthält beispielsweise die Tabellen
Singers
,Albums
undAccounts
.Albums
ist mitSingers
verschränkt und speichert Informationen zu Alben fürSingers
. Die folgende zusammenhängende Gruppe von Anweisungen schreibt neue Zeilen in mehrere Tabellen und enthält keine komplexen Daten Abhängigkeiten.INSERT INTO Singers (SingerId, Name) VALUES(1, "John Doe"); INSERT INTO Singers (SingerId, Name) VALUES(2, "Marcel Richards"); INSERT INTO Albums(SingerId, AlbumId, AlbumTitle) VALUES (1, 10001, "Album 1"); INSERT INTO Albums(SingerId, AlbumId, AlbumTitle) VALUES (1, 10002, "Album 2"); INSERT INTO Albums(SingerId, AlbumId, AlbumTitle) VALUES (2, 10001, "Album 1"); UPDATE Accounts SET Balance = 100 WHERE AccountId = @AccountId;
Spanner optimiert diese Gruppe von DML-Anweisungen, indem die Anweisungen parallel ausgeführt werden. Die Schreibvorgänge werden in der Reihenfolge der Anweisungen in Die Batch-Verarbeitung und verwaltet die Batch-DML-Semantik, wenn eine Anweisung während Ausführung.