データベース アプリケーションでは、主キーが固有の識別子であり、新しい行が主キーの昇順で挿入される事が一般的です。したがって、集合インデックスへの挿入では、ディスクからのランダムな読み取りを必要としません。
一方、セカンダリ
インデックスは通常固有ではなく、セカンダリ
インデックスへの挿入は比較的ランダムな順番で行われます。
この為、InnoDB
で特別な構造が使用される事なく、多数のランダムなディスク
I/O が発生します。
固有でないセカンダリ
インデックスにインデックス
レコードが挿入される場合は、セカンダリ
インデックス ページがすでにバッファ
プール内にあるかどうかが InnoDB
によってチェックされます。すでにある場合は、InnoDB
によってインデックス
ページに直接レコードが挿入されます。バッファ
プール内にインデックス
ページがなかった場合は、InnoDB
によって特別な挿入バッファ構造にレコードが挿入されます。挿入バッファは、その全体がバッファ
プール内に収まるように小さくしてある為、このバッファへの挿入はきわめて高速です。
挿入バッファは、データベース内のセカンダリ インデックス ツリーに定期的にマージされます。インデックス ツリーの同じページ上で複数の挿入をマージする事で、ディスク I/O を削減できます。 挿入バッファによってテーブルへの挿入速度が最大15倍に高められる事が測定されています。
挿入バッファ
マージは、挿入トランザクションがコミットされた
後
まで発生し続けるでしょう。実際、これはサーバがシャットダウンし、再起動する後まで発生し続けます。(項13.5.8.1. 「InnoDB
復旧の強制」
を参照してください。)
挿入バッファ マージは、多くのセカンダリ インデックスが更新される必要があり、多くの行が挿入された時に、何時間もかかる可能性があります。この間はディスクI/Oが増加してしまいます。それにより、ディスク操作をたくさん行うようなクエリはスローダウンしてしまいます。この他の主なバックグラウンドI/Oスレッドは、パージスレッドです。(項13.5.12. 「マルチバージョンの実装」 を参照してください。)