Best Practices für die Datenbearbeitungssprache

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 alle INSERT-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 und Accounts. Albums ist mit Singers verschränkt und speichert Informationen zu Alben für Singers. 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.