web-dev-qa-db-ja.com

MySQL / MariaDB BLOB列がコピーされると、どのデータが複製されますか?

table_1を次のように作成します。

CREATE TABLE table_1 (
    id INT AUTO_INCREMENT PRIMARY KEY,
    some_blob BLOB
);

table_2を次のように作成します。

CREATE TABLE table_2 (
    id INT AUTO_INCREMENT PRIMARY KEY,
    some_blob BLOB
);

私が知りたいのは、このテーブルコピークエリを実行した後です

INSERT INTO table_2 (id, some_blob) SELECT id, some_blob FROM table_1;

some_blobテーブルの各table_1フィールド内の実際のテキストは複製されてディスクに保存されますか、それともDBはBLOBデータを含むディスク位置への複製されたポインタのみを持ちますか?

BLOBコピーが実際のコンテンツの理由の複製を次のように含まなければならない理由の1つの議論:

table_1のBLOBデータへの変更はtable_2でも行われるべきではないため、BLOBコンテンツの複製が必要です。ディスクポインタのみが複製された場合、一方のテーブルでのコンテンツの変更はもう一方のテーブルに反映され、正しいコピー操作のプロパティに違反します。

ここで、このコピー操作を満たすためにDBが実装できる代替方法を紹介します。この代替案は上記の議論は必ずしも真ではないを示しています。 DBは、指定されたINSERTステートメントの実行中にのみディスクポインタを複製でき、テーブルの1つでBLOBデータを変更しようとするUPDATEが発生するたびに、DBはそれを割り当てます。 UPDATEクエリの一部である新しいデータを格納するためのディスク上のより多くのスペース。 BLOBデータセグメントは、それを指すディスクポインターが存在しなくなった場合にのみ削除され、特定のBLOBデータセグメントには、それを指す多くのディスクポインターが含まれる可能性があります。

では、MySQL/MariaDBは、指定されたINSERTステートメントを実行するときに、これらの戦略のどれを使用しますか、それとも別の戦略を使用しますか?

なぜ私はこの質問をしているのですか

現在、同じデータベース内のあるテーブルから別のテーブルに大量のBLOBデータ(1,000万行を超えるBLOBデータ)をコピーするUPDATEクエリをいくつか実行しています。クエリはしばらくの間実行されています。比較している列の一部のインデックスが不十分であるため、これらのクエリがディスクポインタではなくコンテンツを文字通りコピーしているため、またはおそらくこれらの両方の理由により、パフォーマンスが非常に遅いかどうかについて興味があります。

質問の例ではINSERTを使用しています。これは、理解しようとしているデータベース内部の概念を単純化するためです。

1
AjaxLeung

別のコピー。

ディスクポインタだけをコピーするには、「参照カウント」、現在存在しない場所でのロックなどが必要になります。

Yoは、BLOBsを別のテーブルに保持し、何らかの方法でそれらにリンクすることで、そのような実装を行うことができます。重複排除にはMD5(または他のダイジェスト)を使用できます。ただし、バグの複雑さと可能性がメリットを上回っていると思います。

「長い間」-コピーされる行が多い場合同じトランザクション内クラッシュした場合に備えて、ROLLBACKの準備に余分な労力がかかることに注意してください。

1
Rick James