Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 27.1Mb
PDF (A4) - 27.2Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


MySQL 5.6 リファレンスマニュアル  /  ...  /  MyISAM テーブルの一括データロード

8.6.2 MyISAM テーブルの一括データロード

これらのパフォーマンスのヒントは、セクション8.2.2.1「INSERT ステートメントの速度」の高速挿入の一般的なガイドラインを補足するものです。

  • 複数のクライアントが大量の行を挿入する場合のパフォーマンスを向上するには、INSERT DELAYED ステートメントを使用します。セクション13.2.5.2「INSERT DELAYED 構文」を参照してください。この技法は、MyISAM およびその他の一部のストレージエンジンには有効ですが、InnoDB には機能しません。

    注記

    MySQL 5.6.6 現在、INSERT DELAYED は非推奨であり、将来のリリースで削除されます。代わりに INSERT (DELAYED を付けない) を使用してください。

  • MyISAM テーブルでは、データファイルの途中に削除された行がない場合、SELECT ステートメントの実行中に同時に、同時挿入を使用して行を追加できます。セクション8.10.3「同時挿入」を参照してください。

  • 少しの追加作業で、MyISAM テーブルに多数のインデックスがある場合に、テーブルの LOAD DATA INFILE の実行をさらに高速化できます。次の手順を使用します。

    1. FLUSH TABLES ステートメントまたは mysqladmin flush-tables コマンドを実行します。

    2. テーブルのインデックスのすべての使用を削除するには、myisamchk --keys-used=0 -rq /path/to/db/tbl_name を使用します。

    3. LOAD DATA INFILE を使用して、テーブルにデータを挿入します。これはインデックスを更新しないため、非常に高速です。

    4. 今後、テーブルから読み取りだけをする場合は、myisampack を使用してそれを圧縮します。セクション15.2.3.3「圧縮テーブルの特徴」を参照してください。

    5. myisamchk -rq /path/to/db/tbl_name を使用してインデックスを再作成します。これにより、ディスクに書き込む前にメモリー内にインデックスツリーを作成し、大量のディスクシークを回避するため、LOAD DATA INFILE 時のインデックスの更新よりかなり高速になります。結果のインデックスツリーは完全にバランスも取れています。

    6. FLUSH TABLES ステートメントまたは mysqladmin flush-tables コマンドを実行します。

    データを挿入する MyISAM テーブルが空の場合は、LOAD DATA INFILE は先述の最適化を自動的に実行します。自動の最適化と明示的に手順を使用することの主な違いは、サーバーに LOAD DATA INFILE ステートメントの実行時に、インデックスの再作成で割り当てさせることができる量より、myisamchk ではインデックスの作成のためにはるかに多くの一時メモリーを割り当てることができることです。

    myisamchk の代わりに次のステートメントを使用して、MyISAM テーブルの一意でないインデックスを無効または有効にすることもできます。これらのステートメントを使用すると、FLUSH TABLE 操作をスキップできます。

    ALTER TABLE tbl_name DISABLE KEYS;
    ALTER TABLE tbl_name ENABLE KEYS;
  • 非トランザクションテーブルに対して、複数ステートメントで実行される INSERT 操作を高速化するには、テーブルをロックします。

    LOCK TABLES a WRITE;
    INSERT INTO a VALUES (1,23),(2,34),(4,33);
    INSERT INTO a VALUES (8,26),(6,29);
    ...
    UNLOCK TABLES;

    これは、すべての INSERT ステートメントの完了後に、インデックスバッファーが 1 回だけディスクにフラッシュされるため、パフォーマンスにメリットがあります。通常は、INSERT ステートメントの数と同じだけ、インデックスバッファーのフラッシュが行われます。すべての行を 1 つの INSERT で挿入できる場合は、明示的なロックステートメントは必要ありません。

    ロックは複数接続テストの合計時間も短縮しますが、個々の接続がロックを待機するため、それらの最大待機時間は長くなることがあります。次のように 5 台のクライアントが同時に挿入の実行を試みるとします。

    • 接続 1 は 1000 回の挿入を実行します

    • 接続 2、3、および 4 は 1 回の挿入を実行します

    • 接続 5 は 1000 回の挿入を実行します

    ロックを使用しない場合、接続 2、3、および 4 は 1 と 5 の前に終了します。ロックを使用した場合、接続 2、3、および 4 は 1 または 5 の前に終了しない可能性がありますが、合計時間は約 40% 高速化するはずです。

    MySQL では、INSERTUPDATE、および DELETE 操作はきわめて高速ですが、約 5 回超の連続した挿入や更新を実行するすべての操作の周囲にロックを追加することによって、全体のパフォーマンスを向上できます。著しく多くの連続した挿入を実行する場合、LOCK TABLES のあとにときどき (1,000 行程度ごとに) UNLOCK TABLES を実行して、ほかのスレッドのテーブルへのアクセスを許可できます。これによってもパフォーマンスの向上が得られます。

    上記の戦略を使用した場合でも、データのロードには LOAD DATA INFILE より INSERT の方がはるかに遅くなります。

  • MyISAM テーブルの LOAD DATA INFILEINSERT の両方に対してパフォーマンスを向上するには、key_buffer_size システム変数を増やして、キーキャッシュを拡張します。セクション8.11.2「サーバーパラメータのチューニング」を参照してください。


User Comments
  Posted by Мих ТехСпец on January 7, 2014
Why the statements
ALTER TABLE tbl_name DISABLE KEYS;
ALTER TABLE tbl_name ENABLE KEYS;
it is to make LOAD DATA INFILE run even faster ONLY?

This statements are good way to speed up INSERT VALUES operations.

I have good result for inserting very big tables (more than 40 mil. rows).
Sign Up Login You must be logged in to post a comment.