このページでは、データ操作言語(DML)とパーティション化 DML を使用するベスト プラクティスについて説明します。
WHERE 句を使用してロックのスコープを狭める
DML ステートメントを読み取り / 書き込みトランザクション内で実行します。Cloud Spanner がデータを読み取るとき、読み取る行範囲の一部に対する共有読み取りロックを取得します。具体的には、アクセスする列に対してのみロックを取得します。ロックには、WHERE
句のフィルタ条件と一致しないデータを含めることが可能です。
Cloud Spanner が DML ステートメントを使用してデータを変更するとき、変更する特定のデータに対して排他ロックを取得します。また、データの読み取り時と同様に共有ロックを取得します。リクエストに大きな行範囲やテーブル全体が含まれている場合、共有ロックによって他のトランザクションが並行して完了しない可能性があります。
データをできるだけ効率的に変更するには、Cloud Spanner で必要な行のみを読み取る WHERE
句を使用します。主キーまたはセカンダリ インデックスのキーに対するフィルタを使用して、この目標を達成できます。WHERE
句は共有ロックのスコープを制限し、Cloud Spanner で更新をより効率的に処理できるようにします。
たとえば、Singers
テーブルに含まれているあるミュージシャンが名前を変更した場合、データベース内のその名前を更新する必要があります。次の DML ステートメントを実行できますが、Cloud Spanner がテーブル全体を強制的にスキャンし、テーブル全体を対象とする共有ロックを取得します。そのため、Cloud Spanner は必要以上に多くのデータを読み取る必要があり、並行トランザクションでデータを並行して変更できません。
-- 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";
更新を効率化するには、SingerId
列を WHERE
句に含めます。SingerId
列は、Singers
テーブルの唯一の主キー列です。
-- RECOMMENDED: INCLUDING THE PRIMARY KEY COLUMN IN THE WHERE CLAUSE
UPDATE Singers SET FirstName = "Marcel"
WHERE FirstName = "Marc" AND LastName = "Richards" AND SingerId = 1;
同じトランザクション内で DML ステートメントとミューテーションを使用しない
Cloud Spanner は、サーバー側で DML ステートメントを使用して実行された挿入、更新、削除をバッファに保存します。この結果は、同じトランザクション内の後続の SQL ステートメントと DML ステートメントで参照できます。この動作は Mutation API とは異なります。Cloud Spanner は、クライアント側でミューテーションをバッファに保存し、commit オペレーションでサーバー側にミューテーションを送信します。このため、commit リクエストのミューテーションは、同じトランザクション内の SQL ステートメントまたは DML ステートメントで参照できません。
一部のオペレーションは Mutation API でのみサポートされているため、insert_or_update のように、同じトランザクションで DML ステートメントとミューテーションを組み合わせることができます。たとえば、insert_or_update
です。commit リクエストでトランザクションに DML ステートメントとミューテーションの両方が含まれている場合、Cloud Spanner はミューテーションの前に DML ステートメントを実行します。クライアント ライブラリ コードの実行順序を考慮する必要がないようにするには、1 つのトランザクション内に DML ステートメントまたはミューテーションのいずれかを使用します。両方を使用する必要はありません。両方を使用する場合は、トランザクションの最後で書き込みをバッファに保存します。
commit タイムスタンプを書き込むには PENDING_COMMIT_TIMESTAMP 関数を使用する
DML ステートメントで commit タイムスタンプを作成するには、PENDING_COMMIT_TIMESTAMP
関数を使用します。トランザクションが commit されると、Cloud Spanner が commit タイムスタンプを選択します。
パーティション化 DML と日付 / タイムスタンプ関数
パーティション化 DML は 1 つ以上のトランザクションを使用します。これらのトランザクションは異なる時間に実行され、commit される可能性があります。日付関数またはタイムスタンプ関数を使用すると、変更した行に異なる値が格納される可能性があります。
バッチ DML を使用して 1 つのリクエストで複数の DML を送信する
バッチ DML を使用すると、1 つのリクエストで複数の DML を送信できます。この方法により、必要なクライアントとサーバーとの往復が 1 回だけになり、レイテンシが短縮されます。