web-dev-qa-db-ja.com

MySQL:テーブル間でビッグデータの移行を実行する

2つのInnoDBテーブル間でデータを移行したい。

現在、私はこのクエリを実行しています:

INSERT INTO table_a SELECT * FROM table_b;

データセットが大きくなった場合、CPUの過負荷を回避する最良の方法は何ですか?

ありがとう

7
Mich Dart

InnoDBを使用しているので、次のことをお勧めします。

提案#1

INSERT、UPDATE、DELETEを行う場合は、次のようにテーブルを一括読み込みします。

CREATE TABLE table_new LIKE table_a;
INSERT INTO table_new SELECT * FROM table_b;
ALTER TABLE table_a RENAME table_old;
ALTER TABLE table_new RENAME table_a;
DROP TABLE table_old;

INSERTとSELECTのみを行う場合は、新しいエントリをテーブルにロードします。 table_aおよびtable_bの主キーがidであると想定して、次のようにロードを実行します。

CREATE TABLE table_new LIKE table_a;
INSERT INTO table_new SELECT B.* FROM table_b B
LEFT JOIN table_a A USING (id) WHERE A.id IS NULL;
INSERT INTO table_a SELECT * FROM table_new;
DROP TABLE table_new;

提案#2:InnoDBを複数のCPU用に調整する

MySQL 5.5を使用していることを確認してください。 MySQL 5.1.38以降を使用している場合は、 InnoDB Plugin をインストールする必要があります。 MySQl 5.1.37以前の場合は、MySQLにアップグレードしてください。

それが完了したら(または、MySQL 5.5がすでにある場合)、複数のCPU向けにInnoDBを調整する必要があります。ホイールを再発明するのではなく、これを行う方法と理由に関する私の過去の投稿を以下に示します。

試してみる !!!

バッファ、ログファイルなど、他のことを提案できます。私はこれらの2つの懸念のみに対処しました。

2
RolandoMySQLDBA

この場合、通常、次のような--tabオプションを使用したmysqldumpが最善の解決策です。

mysqldum --tab=/path/to/serverlocaldir --single-transaction <database> table_a

tabオプションは2つのファイルを生成し、1つのファイル-table_a.sql-はテーブル作成ステートメントのみを含み、oherファイル-table_a.txt-はタブ区切りデータを含みます。

これで、新しいテーブルを作成できます

create table table_b like table_a;

次に、LOAD DATAを介して新しいテーブルにデータをロードするだけで、テーブルの名前は無視されます。

LOAD DATA INFILE '/path/to/serverlocaldir/table_a.txt' 
  INTO TABLE table_b FIELDS TERMINATED BY '\t' ...

LOAD DATAは通常、INSERTステートメントを使用するよりも20倍高速です。

お役に立てれば

1
Cristian Porta