これらのパフォーマンスのヒントは、セクション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
の実行をさらに高速化できます。次の手順を使用します。FLUSH TABLES
ステートメントまたは mysqladmin flush-tables コマンドを実行します。テーブルのインデックスのすべての使用を削除するには、myisamchk --keys-used=0 -rq
/path/to/db/tbl_name
を使用します。LOAD DATA INFILE
を使用して、テーブルにデータを挿入します。これはインデックスを更新しないため、非常に高速です。今後、テーブルから読み取りだけをする場合は、myisampack を使用してそれを圧縮します。セクション15.2.3.3「圧縮テーブルの特徴」を参照してください。
myisamchk -rq
/path/to/db/tbl_name
を使用してインデックスを再作成します。これにより、ディスクに書き込む前にメモリー内にインデックスツリーを作成し、大量のディスクシークを回避するため、LOAD DATA INFILE
時のインデックスの更新よりかなり高速になります。結果のインデックスツリーは完全にバランスも取れています。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 では、
INSERT
、UPDATE
、およびDELETE
操作はきわめて高速ですが、約 5 回超の連続した挿入や更新を実行するすべての操作の周囲にロックを追加することによって、全体のパフォーマンスを向上できます。著しく多くの連続した挿入を実行する場合、LOCK TABLES
のあとにときどき (1,000 行程度ごとに)UNLOCK TABLES
を実行して、ほかのスレッドのテーブルへのアクセスを許可できます。これによってもパフォーマンスの向上が得られます。上記の戦略を使用した場合でも、データのロードには
LOAD DATA INFILE
よりINSERT
の方がはるかに遅くなります。 MyISAM
テーブルのLOAD DATA INFILE
とINSERT
の両方に対してパフォーマンスを向上するには、key_buffer_size
システム変数を増やして、キーキャッシュを拡張します。セクション8.11.2「サーバーパラメータのチューニング」を参照してください。