2

挿入の mysql パフォーマンスを改善する方法を研究していました。

シナリオについては、忙しい日に、3 秒ごとに大きなテーブルで約 3000 行、中規模のテーブルでさらに 100 行、小さなテーブルで約 30 行を同時に処理します。これは 24 時間継続する必要があり、30.000 ~ 40.000 行のみの重要な部分を選択してから、3 つのテーブルすべてをフラッシュします。

だから、私はmysql 5.5.29を使用しています。すべてのテーブルは innodb を使用しており、インデックスと主キーはほとんどありません。

質問については、これらの挿入にメモリ エンジン テーブルを使用し、それらをプライマリ テーブルに移動することについてのコメントを見ました。

「LOCK TABLE を使用すると .. WRITE を使用すると挿入が高速化される可能性がありますが、行をロードするだけでなく処理するときに、リーダーがロックアウトされます。主キーの選択 (0 秒近くかかるはずです) は、私のローダーは 1000 行のバッチの読み込みでビジーです。

非常に良い回避策は、新しい行を一時テーブルに配置し、そのテーブルをときどき単一のトランザクションでフラッシュすることです。これにより、すべてのチェックと変換が一時テーブルで既に行われているため、挿入が非常に高速になります。

CREATE TEMPORARY TABLE ..._temp (....) ENGINE=MEMORY;

-- Loop from here --
DELETE FROM .._temp;
INSERT INTO .._temp ... VALUES (...);
INSERT INTO .._temp ... VALUES (...);

LOCK TABLE ... WRITE, ..._temp READ;
INSERT INTO ... SELECT * FROM ..._temp;
UNLOCK TABLES;
-- Repeat until done --

DROP TABLE ..._temp;

私のシステムで見たのは、テーブルをロックするときとほぼ同じ速度で INSERT が実行されることですが、ローダーが実行されているとき、クライアントはパフォーマンスの低下にまったく気付かないということです。」

ソース

その場合、メモリエンジンを使用するのは理にかなっていますか? 行にアクセスする必要がある場合にテーブルロックを回避するために innodb を使用する必要がありますか、それとも速度のために myisam を使用する必要がありますか?

4

1 に答える 1

4

毎日テーブルをワイプする必要があるが、最初にテーブルからデータを取得する必要がある場合。最善の策は、既存の完全なテーブルを新しい空のテーブルとすばやく交換し、後で完全なテーブルに対して必要なデータ操作を行うことです。方法は次のとおりです。

最初に、操作しようとしているテーブルと同じようにテーブルを作成します。

CREATE TABLE big_table_temp LIKE big_table;

大きなテーブルと同じスキーマを持つ空のテーブルができました。

次に、テーブルの名前を変更してそれらを交換します。

RENAME TABLE big_table TO big_table_archive, big_table_temp TO big_table;

これの利点は、MySQL がディスク上のバイナリ データベース ファイルの名前を変更するだけなので、この操作が基本的に瞬時に行われることです。操作を全体として成功または失敗させたいので、このような 1 つのクエリで両方の名前変更操作があることを確認してください。

big_table_archiveでのライブ クエリがブロックされることを心配することなく、必要に応じてデータを抽出して操作できますbig_table

于 2013-03-02T01:13:44.473 に答える