web-dev-qa-db-ja.com

MySQLはすべてのレコードを1つのテーブルから別のテーブルに効率的にコピーします

これを行う、1つのテーブルから別のテーブルにすべてのレコードをコピーするより効率的で手間がかからない方法はありますか。

INSERT INTO product_backup SELECT * FROM product

通常、productテーブルには約50,000レコードが保持されます。どちらのテーブルも構造は同じで、31列あります。これがnotのデータベース設計であることを指摘したいのですが、レガシーシステムを継承しています。

20
crmpicco

不足していることが1つだけあります。特に、InnoDBを使用している場合、SELECTステートメントにORDER BY句を明示的に追加して、主キー(クラスター化インデックス)の順序で行を挿入していることを確認します。

INSERT INTO product_backup SELECT * FROM product ORDER BY product_id

不要な場合は、バックアップテーブルのセカンダリインデックスを削除することを検討してください。これにより、サーバーの負荷も軽減されます。

最後に、InnoDBを使用している場合は、必要な行ロックの数を減らし、両方のテーブルを明示的にロックするだけです。

LOCK TABLES product_backup WRITE;
LOCK TABLES product READ;
INSERT INTO product_backup SELECT * FROM product ORDER BY product_id;
UNLOCK TABLES;

行のロックは非常に速いので(テーブルロックほど速くはありませんが)、ロックの内容はおそらく大きな違いはありませんが、あなたが尋ねたので。

19
Marcus Adams

これは、あるテーブルから別のテーブルにレコードをコピーする最良の方法だと思います。このようにして、ターゲットテーブルの既存のインデックスも保持します。

12
mysqldump -R --add-drop-table db_name table_name > filepath/file_name.sql

これは、インポート時に既存のテーブルを削除するためのドロップオプションを使用して、指定されたテーブルのダンプを取得します。その後、

mysql db_name < filepath/file_name.sql
4
satdev86

DROP宛先テーブル:

DROP TABLE DESTINATION_TABLE;
CREATE TABLE DESTINATION_TABLE AS (SELECT * FROM SOURCE_TABLE);
2
Ice Cream

これは50kのテーブルにはふさわしくないと思いますが、データベースダンプがあれば、そこからテーブルをリロードできます。別のテーブルにテーブルをロードしたいので、sedコマンドでダンプ内のテーブル名を変更できます:ここにいくつかのヒントがあります: http://blog.tsheets.com/2008/tips-tricks/ mysql-restoring-a-single-table-from-a-huge-mysqldump-file.html

代替策(設計によって異なります)は、複製されたテーブルもデータを取得できるように、元のテーブル挿入でトリガーを使用することです。

そしてより良い代替案は、別のMySQLインスタンスを作成し、それをマスター/スレーブ構成で実行するか、毎日のダンプマスター/ロードスレーブ方式で実行することです。

1
mihaisimi