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
を使用しています。これは、理解しようとしているデータベース内部の概念を単純化するためです。
別のコピー。
ディスクポインタだけをコピーするには、「参照カウント」、現在存在しない場所でのロックなどが必要になります。
Yoは、BLOBs
を別のテーブルに保持し、何らかの方法でそれらにリンクすることで、そのような実装を行うことができます。重複排除にはMD5
(または他のダイジェスト)を使用できます。ただし、バグの複雑さと可能性がメリットを上回っていると思います。
「長い間」-コピーされる行が多い場合同じトランザクション内クラッシュした場合に備えて、ROLLBACK
の準備に余分な労力がかかることに注意してください。