InnoDBのインデックスページ構造、挿入バッファ、適応ハッシュインデックスについての簡単な説明

InnoDBのインデックスページ構造、挿入バッファ、適応ハッシュインデックスについての簡単な説明

InnoDB インデックスの物理構造

すべての InnoDB インデックスは Btree インデックスであり、インデックス レコードはリーフに格納され、デフォルトのインデックス ページ サイズは 16K です。新しいレコードが挿入されると、InnoDB は将来の挿入および更新操作のために空きページ サイズの 1/16 を残しておこうとします。

インデックス レコードがインデックス レコード サイズの順序どおりに挿入された場合、インデックスはページ全体のサイズの 15/16 も埋めます。挿入順序が完全にランダムである場合、インデックス ページは基本的に 1/2 から 15/16 まで自己構築されて埋められます。フィルファクターが 1/2 未満の場合、InnoDB は b ツリーの再構築を試みます。

MySQL 5.6 以降では、innodb_page_size パラメータを使用して、現在のインスタンス内の各インデックス ページのサイズを設定できます。一度設定すると、元に戻すことはできません。推奨される構成は通常、16K、8K、または 4K です。さらに、MySQLインスタンスがデフォルト値とは異なるinnodb_page_size Aに設定されている場合、Aとは異なる値を持つ他のインスタンス上のファイルを使用できなくなります(たとえば、物理的なバックアップと復元を行うため)。

バッファリングを挿入

データベース アプリケーションは通常、主キーの順序でデータを挿入します。この場合、クラスター化インデックスの順序は主キー値の順序とまったく同じなので、挿入操作によってランダム IO が大幅に削減されます。

一方、セカンダリ インデックスは通常は一意ではないため、データは比較的ランダムな順序でセカンダリ インデックスに挿入されます。同様に、削除および更新操作がデータ ページに影響する場合、セカンダリ インデックス上で互いに隣接していないインデックスへの変更が伴います。これにより、ランダム IO が大量に発生します。

一意でないセカンダリ インデックスにレコードを挿入したり、レコードを削除したりする場合、InnoDB はまずセカンダリ インデックス ページがバッファー プール内にあるかどうかを確認します。バッファ プール内にある場合、InnoDB はメモリ内で直接インデックス ページを変更します。インデックスがバッファ プール内にもない場合、InnoDB は挿入バッファに変更を記録します。挿入バッファは通常は小さいため、バッファ プール内に完全に保持され、頻繁に更新されます。この変更プロセスは変更バッファリングと呼ばれます(通常、挿入操作にのみ影響するため、挿入バッファリングとも呼ばれ、データ構造は挿入バッファです)。

挿入バッファをフラッシュするためのディスクI/O

では、挿入バッファリングによってランダム IO はどのように削減されるのでしょうか?時々、挿入バッファは挿入バッファ内のセカンダリ非一意インデックスをマージします。通常、N 個の変更を同じ Btree インデックスのインデックス ページにマージするため、多くの IO 操作が節約されます。テストの結果、insertbuffer は挿入速度を 15 倍に向上させることができました。

トランザクションがコミットされた後も、挿入バッファは書き込みをマージしている可能性があります。したがって、DB が異常に再起動された場合、リカバリ フェーズで大量のセカンダリ インデックスを更新または挿入する必要があるときに、挿入バッファーに数時間かかることもあります。このフェーズでは、ディスク IO が増加し、ディスク バウンド クエリのパフォーマンスが大幅に低下します。

適応ハッシュインデックス

アダプティブ ハッシュ インデックス (AHI) により、バッファー プールに十分なメモリと特定のワークロードがある場合、トランザクション機能と安定性を犠牲にすることなく、InnoDB はメモリ内データベースのように見えます。この機能は、動的パラメータである innodb_adaptive_hash_index によって制御されます。デフォルト値はオンで、これはアダプティブ ハッシュ インデックスがオンになっていることを意味します。AHI をオフにすると、組み込みハッシュ テーブルはすぐにクリアされ、B-TREE インデックスに直接アクセスしながら、通常の操作を続行できます。 AHI を再度有効にすると、ハッシュ テーブルが再構築されます。

検索パターンを観察することにより、MySQL はインデックス キーのプレフィックスを使用してハッシュ インデックスを作成します。このプレフィックスは任意の長さにすることができ、B ツリー全体ではなく、B ツリー上の一部の値だけになることもあります。ハッシュ インデックスが検出され、頻繁にアクセスされるインデックス ページにハッシュ インデックスが作成されます。

テーブルの大部分がバッファ プール内にある場合、ハッシュ インデックスを作成すると、Btree インデックス値をソートされたポインタに変換することで等価クエリを高速化できます。 Innodb には、インデックスの検索状況を監視できるメカニズムがあります。ハッシュ インデックスを作成することでクエリを最適化できることに気付いた場合は、自動的にハッシュ インデックスを作成するため、「適応型」です。

一部のワークロードでは、ハッシュ インデックス検索によって得られるパフォーマンスの向上が、インデックス検索の監視とハッシュ テーブル構造の維持による追加のオーバーヘッドを上回ります。ただし、高負荷の状況では、アダプティブ ハッシュ インデックスに追加された読み取り/書き込みロックによって、同時実行性の高い結合操作などの競合が発生することもあります。 Like 演算子と % ワイルドカード文字も AHI には適用されません。ワークロードが AHI に適していない場合は、不要なパフォーマンスのオーバーヘッドを回避するために AHI をオフにすることをお勧めします。 MySQL 内の特定の状況で AHI が適切かどうかを予測することは難しいため、実際のワークロード (AHI ありとなし) でストレス テストを実行することをお勧めします。 5.6 以降のバージョンでは、現在はデフォルトで有効になっていますが、より多くのワークロードでアダプティブ ハッシュ インデックスを無効にすることが最適であると見なされるようになります。

ハッシュ インデックスの作成は、多くの場合、既存の B ツリーに基づいて行われます。InnoDB は、B ツリーの検索状況を観察し、任意の長さの B ツリー インデックス プレフィックスを確立することで、ハッシュ インデックスを作成できます。ハッシュ インデックスは、B ツリー インデックスの最も頻繁にアクセスされるページのみを含む部分的なインデックスにすることができます。

show engine innodb status の結果の SEMAPHORES セクションを観察することで、アダプティブ ハッシュ インデックスを使用するかどうかを決定できます。 btr0sea.c ファイルで作成された rw-latch を待機しているスレッドが多数ある場合は、アダプティブ ハッシュ インデックスをオフにすることをお勧めします。以下は私が遭遇したケースのスクリーンショットです。これは高同時実行モードでの AHI 競合の典型的なケースです。AHI をオフにする必要があります。


InnoDB のインデックス ページ構造、挿入バッファ、およびアダプティブ ハッシュ インデックスに関する上記の簡単な説明は、エディターが皆さんと共有する内容のすべてです。これが皆さんの参考になれば幸いです。また、123WORDPRESS.COM をサポートしていただければ幸いです。

以下もご興味があるかもしれません:
  • MySQL InnoDB ロックの概要
  • MySQL の innodb_flush_log_at_trx_commit と sync_binlog を区別する方法
  • MySQL InnoDB ロック メカニズムの詳細な例
  • MySQLテクノロジーにおけるInnoDBロックの詳細な説明
  • MySQLデータベースエンジンをInnoDBに変更する
  • MySQL InnoDB の重要なコンポーネントの概要
  • Mysql InnoDBとMyISAMの違いの分析
  • MySQL innodb B+ツリーの高さを取得する方法
  • MySQL MyISAM と InnoDB の違い
  • MySQLでデータテーブルを作成するときにエンジンMyISAM/InnoDBを設定する
  • MySQL Innodbの主な機能挿入バッファ

<<:  Vue の基本的な手順の例のグラフィック説明

>>:  Shutdown.batを使用してTomcatをシャットダウンすると他のTomcatもシャットダウンしてしまう問題を解決します

推薦する

Vueでaxiosを簡単にカプセル化する方法

Vueにaxiosを挿入する 'axios' から axios をインポートします。...

MySQL の文字セットの不一致によって発生する異常な接続テーブルの解決方法

目次1. 解決策2. MySQLの文字セット文字セット検証ルール次のように簡単なテーブルクエリを実行...

JavaScript における var、let、const の違いの詳細な説明

目次グローバル変数として可変ホイスト一時的なデッドゾーンブロックスコープ重複したステートメント宣言さ...

MySQLの暗黙的な変換問題の解決

1. 問題の説明 root@mysqldb 22:12: [xucl]> テーブル t1\G ...

TypeScript 環境を構築して VSCode にデプロイする詳細な手順

目次TypeScript環境の構築ステップ1: Taobaoミラーをダウンロードするステップ2: T...

MYSQL スロークエリとログ設定とテスト

1. はじめにスロークエリログを有効にすると、MySQL は指定された時間を超えるクエリステートメン...

React と Threejs を使用して VR パノラマ プロジェクトを作成する詳細なプロセス

最近、 Three.jsでReactを使用して、720 度のパノラマ写真を閲覧できるプロジェクトを構...

vuexの強制リフレッシュによるデータ損失問題の分析

vuex 永続状態基本原則: すべての vuex データをローカルストレージに保存し、ページが更新さ...

Docker 入門インストールチュートリアル (初心者版)

ドクター紹介: Docker はコンテナ関連の技術です。簡単に言うと、さまざまなソフトウェアを実行で...

GZIP 圧縮 Tomcat と Web パフォーマンスの改善プロセス図

1. はじめに最近、あるプロジェクトに取り組んでいたのですが、サーバーからクライアントに返される J...

ZabbixはPSK共有キーを使用してサーバーとエージェント間の通信を暗号化します。

Zabbix バージョン 3.0 以降、Zabbix サーバー、Zabbix プロキシ、Zabbi...

JDカルーセル効果を実現するための純粋なHTMLとCSS

JD カルーセルは、動的な効果を追加せず、主に位置決めの知識を使用して、純粋な HTML と CS...

最小限の展開で CentOS8 に OpenStack Ussuri をインストールする方法の詳細なチュートリアル

CentOS8 に最小限のデプロイメントで OpenStack Ussuri をインストールするため...

MySQL カーソルの概念と使用法の詳細な説明

この記事では、例を使用して MySQL カーソルの概念と使用方法を説明します。ご参考までに、詳細は以...

Tomcat9 Windows サービスのインストールに関する詳細なチュートリアル

1. 準備1.1 service.bat を含む tomcat 圧縮パッケージをダウンロードします。...