任意のINSERT ... SELECT ...
クエリは
LIMIT ... OFFSET
を使用したクエリ ソーステーブルを進むにつれて、だんだん遅くなります。チャンクあたり10,000行の場合、そのクエリを10,000回実行する必要があります。各行を最初からやり直してテーブルをスキャンし、新しいオフセットに到達する必要があります。
何をしても、1億行のコピーには時間がかかります。たくさんの仕事をしています。
pt-archiver を使用します 、この目的のために設計された無料のツール。 「チャンク」(またはサブセット)の行を処理します。各チャンクが0.5秒かかるように、チャンクのサイズを動的に調整します。
メソッドとpt-archiverの最大の違いは、pt-archiverがLIMIT ... OFFSET
を使用しないことです。 、主キーインデックスに沿って移動し、位置ではなく値で行のチャンクを選択します。したがって、すべてのチャンクがより効率的に読み取られます。
コメントを再確認してください:
バッチサイズを小さくし、反復回数を増やすと、パフォーマンスの問題が悪化すると予想されます。 、良くない。
その理由は、LIMIT
を使用する場合です。 OFFSET
を使用 、すべてのクエリはテーブルの先頭からやり直し、OFFSET
までの行をカウントする必要があります 価値。これは、テーブルを反復処理するにつれてますます長くなります。
OFFSET
を使用して20,000の高価なクエリを実行する 10,000の同様のクエリを実行するよりも時間がかかります。最もコストのかかる部分は、5,000行または10,000行を読み取ったり、宛先テーブルに挿入したりすることではありません。高価な部分は、最大50,000,000行を何度もスキップすることになります。
代わりに、値でテーブルを反復処理する必要があります オフセットではありません。
INSERT IGNORE INTO Table2(id, field2, field3)
SELECT f1, f2, f3
FROM Table1
WHERE id BETWEEN rowOffset AND rowOffset+limitSize;
ループの前に、MIN(id)とMAX(id)を照会し、rowOffset
を開始します 最小値で、最大値までループします。
これがpt-archiverの仕組みです。