テーブルに対して INSERT
、UPDATE
、および DELETE
操作が実行されると、インデックス付きカラムの値 (特に副キーの値) は多くの場合、ソートされた順番にならないため、セカンダリインデックスを最新の状態にするために大量の I/O が必要になります。InnoDB
は、挿入バッファーを備えています。これは、関連するページがバッファープール内にない場合にセカンダリインデックスエントリへの変更をキャッシュすることにより、そのページをディスクから読み取らないことで I/O 操作を回避するものです。バッファリングされた変更は、そのページがバッファープールにロードされたときにマージされ、更新されたページはあとで通常のメカニズムを使用してディスクにフラッシュされます。InnoDB
のメインスレッドは、それらのバッファリングされた変更を、サーバーがほぼアイドル状態にあるときと低速シャットダウン中にマージします。
これにより、ディスクの読み取りや書き込みが少なくなる場合があるため、この機能は、I/O に依存するワークロード (たとえば、一括挿入などの大量の DML 操作を含むアプリケーション) にとってもっとも価値があります。
ただし、挿入バッファーはバッファープールの一部を占有するため、データページをキャッシュするために使用できるメモリーが減少します。ワーキングセットがバッファープールにほぼ収まる場合や、テーブルのセカンダリインデックスが比較的少ない場合は、挿入バッファリングを無効にすると役立つことがあります。ワーキングセットがバッファープールに完全に収まる場合は、挿入バッファリングはバッファープール内にないページにしか適用されないため、追加で課せられるオーバーヘッドはありません。
InnoDB
がどの程度挿入バッファリングを実行するかは、システム構成パラメータ innodb_change_buffering
を使用して制御できます。挿入操作、削除操作 (インデックスレコードが最初に削除対象としてマークされるとき)、およびパージ操作 (インデックスレコードが物理的に削除されるとき) でのバッファリングを有効または無効にすることができます。更新操作は、挿入と削除の組み合わせとして表されます。MySQL 5.5 以降では、デフォルト値が inserts
から all
に変更されました。
innodb_change_buffering
の許可される値は次のとおりです。
-
all
デフォルト値: バッファーの挿入、削除のマーキング操作、およびパージ。
-
none
どの操作もバッファリングしません。
-
inserts
挿入操作をバッファリングします。
-
deletes
削除のマーキング操作をバッファリングします。
-
changes
挿入と削除のマーキングの両方をバッファリングします。
-
purges
バックグラウンドで実行される物理的な削除操作をバッファリングします。
このパラメータの値は MySQL オプションファイル (my.cnf
または my.ini
) で設定するか、あるいは SET GLOBAL
コマンド (これには SUPER
権限が必要です) で動的に変更できます。この設定を変更すると、新しい操作のバッファリングに影響を与えます。すでにバッファリングされたエントリのマージは影響を受けません。
INSERT
、UPDATE
、および DELETE
ステートメントの高速化の詳細は、セクション8.2.2「DML ステートメントの最適化」を参照してください。