Praktik terbaik Bahasa Manipulasi Data

Halaman ini menjelaskan praktik terbaik untuk menggunakan Bahasa Manipulasi Data (DML) dan DML Partisi.

Menggunakan klausa WHERE untuk mengurangi cakupan kunci

Anda menjalankan pernyataan DML di dalam transaksi baca-tulis. Saat membaca data, Spanner akan memperoleh kunci baca bersama pada bagian terbatas dari rentang baris yang Anda baca. Secara khusus, API ini memperoleh kunci ini hanya pada kolom yang Anda akses. Kunci dapat menyertakan data yang tidak memenuhi kondisi filter klausa WHERE.

Saat mengubah data menggunakan pernyataan DML, Spanner akan memperoleh kunci eksklusif pada data tertentu yang Anda ubah. Selain itu, metode ini memperoleh kunci bersama dengan cara yang sama seperti saat Anda membaca data. Jika permintaan Anda menyertakan rentang baris yang besar, atau seluruh tabel, kunci bersama dapat mencegah transaksi lain melakukan progres secara paralel.

Untuk mengubah data seefisien mungkin, gunakan klausa WHERE yang memungkinkan Spanner hanya membaca baris yang diperlukan. Anda dapat mencapai sasaran ini dengan filter pada kunci utama, atau pada kunci indeks sekunder. Klausa WHERE membatasi cakupan kunci bersama dan memungkinkan Spanner memproses pembaruan secara lebih efisien.

Misalnya, salah satu musisi di tabel Singers mengubah nama depannya, dan Anda perlu memperbarui nama tersebut di database. Anda dapat menjalankan pernyataan DML berikut, tetapi tindakan ini akan memaksa Spanner memindai seluruh tabel dan memperoleh kunci bersama yang mencakup seluruh tabel. Akibatnya, Spanner harus membaca lebih banyak data daripada yang diperlukan, dan transaksi serentak tidak dapat mengubah data secara paralel:

-- 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";

Agar pembaruan lebih efisien, sertakan kolom SingerId dalam klausa WHERE. Kolom SingerId adalah satu-satunya kolom kunci utama untuk tabel Singers:

-- ANTI-PATTERN: SENDING AN UPDATE THAT MUST SCAN THE ENTIRE TABLE

UPDATE Singers SET FirstName = "Marcel"
WHERE FirstName = "Marc" AND LastName = "Richards"

Jika tidak ada indeks di FirstName atau LastName, Anda harus memindai seluruh tabel untuk menemukan penyanyi target. Jika Anda tidak ingin menambahkan indeks sekunder untuk membuat pembaruan lebih efisien, sertakan kolom SingerId dalam klausa WHERE.

Kolom SingerId adalah satu-satunya kolom kunci utama untuk tabel Singers. Untuk menemukannya, jalankan SELECT dalam transaksi hanya baca terpisah sebelum transaksi update:


  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;

Menghindari penggunaan pernyataan dan mutasi DML dalam transaksi yang sama

Spanner menyimpan penyisipan, pembaruan, dan penghapusan yang dilakukan menggunakan pernyataan DML di sisi server, dan hasilnya terlihat oleh pernyataan SQL dan DML berikutnya dalam transaksi yang sama. Perilaku ini berbeda dengan Mutation API, dengan Spanner buffering mutasi di sisi klien dan mengirim mutasi sisi server sebagai bagian dari operasi commit. Akibatnya, mutasi dalam permintaan commit tidak terlihat oleh pernyataan SQL atau DML dalam transaksi yang sama.

Hindari penggunaan pernyataan DML dan mutasi dalam transaksi yang sama. Jika menggunakan keduanya dalam transaksi yang sama, Anda harus memperhitungkan urutan eksekusi dalam kode library klien. Jika transaksi berisi pernyataan DML dan mutasi dalam permintaan yang sama, Spanner akan mengeksekusi pernyataan DML sebelum mutasi.

Untuk operasi yang hanya didukung menggunakan mutasi, Anda dapat menggabungkan pernyataan DML dan mutasi dalam transaksi yang sama—misalnya, insert_or_update.

Jika Anda menggunakan keduanya, buffer hanya akan menulis di bagian akhir transaksi.

Menggunakan fungsi PENDING_COMMIT_TIMESTAMP untuk menulis stempel waktu commit

GoogleSQL

Anda menggunakan fungsi PENDING_COMMIT_TIMESTAMP untuk menulis stempel waktu commit dalam pernyataan DML. Spanner memilih stempel waktu commit saat transaksi di-commit.

PostgreSQL

Anda menggunakan fungsi SPANNER.PENDING_COMMIT_TIMESTAMP() untuk menulis stempel waktu commit dalam pernyataan DML. Spanner memilih stempel waktu commit saat transaksi di-commit.

DML yang dipartisi serta fungsi tanggal dan stempel waktu

DML yang dipartisi menggunakan satu atau beberapa transaksi yang mungkin berjalan dan melakukan commit pada waktu yang berbeda. Jika Anda menggunakan fungsi date atau timestamp, baris yang diubah mungkin berisi nilai yang berbeda.

Meningkatkan latensi dengan DML Batch

Untuk mengurangi latensi, gunakan DML batch untuk mengirim beberapa pernyataan DML ke Spanner dalam satu perjalanan bolak-balik klien-server.

DML Batch dapat menerapkan pengoptimalan ke grup pernyataan dalam batch untuk memungkinkan pembaruan data yang lebih cepat dan lebih efisien.

  • Menjalankan operasi tulis dengan satu permintaan

    Spanner secara otomatis mengoptimalkan grup berdekatan dari pernyataan batch INSERT, UPDATE, atau DELETE serupa yang memiliki nilai parameter yang berbeda, jika tidak melanggar dependensi data.

    Misalnya, pertimbangkan skenario saat Anda ingin menyisipkan kumpulan baris baru yang besar ke dalam tabel yang disebut Albums. Agar Spanner dapat mengoptimalkan semua pernyataan INSERT yang diperlukan menjadi satu tindakan sisi server yang efisien, mulailah dengan menulis pernyataan DML yang sesuai yang menggunakan parameter kueri SQL:

    INSERT INTO Albums (SingerId, AlbumId, AlbumTitle) VALUES (@Singer, @Album, @Title);
    

    Kemudian, kirim batch DML ke Spanner yang memanggil pernyataan ini berulang kali dan berturut-turut, dengan pengulangan yang hanya berbeda dalam nilai yang Anda tautkan ke tiga parameter kueri pernyataan. Spanner mengoptimalkan pernyataan DML yang identik secara struktural ini menjadi satu operasi sisi server sebelum menjalankannya.

  • Menjalankan operasi tulis secara paralel

    Spanner secara otomatis mengoptimalkan grup pernyataan DML yang berdekatan dengan mengeksekusinya secara paralel jika tidak melanggar dependensi data. Pengoptimalan ini memberikan manfaat performa untuk kumpulan pernyataan DML dalam batch yang lebih luas karena dapat diterapkan ke campuran jenis pernyataan DML (INSERT, UPDATE, dan DELETE) serta ke pernyataan DML berparameter atau tidak berparameter.

    Misalnya, skema contoh kami memiliki tabel Singers, Albums, dan Accounts. Albums diselingi dalam Singers dan menyimpan informasi tentang album untuk Singers. Grup pernyataan yang berurutan berikut menulis baris baru ke beberapa tabel dan tidak memiliki dependensi data yang kompleks.

    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 mengoptimalkan grup pernyataan DML ini dengan menjalankan pernyataan secara paralel. Operasi tulis diterapkan sesuai urutan pernyataan dalam batch dan mempertahankan semantik DML batch jika pernyataan gagal selama eksekusi.