MySQL InnoDB インデックス拡張の詳細な説明

MySQL InnoDB インデックス拡張の詳細な説明

インデックス拡張: InnoDB は、プライマリ キー列をそのインデックスに追加することで、各セカンダリ インデックスを自動的に拡張します。次のテーブル構造を作成します。

mysql> テーブル t1 を作成します (
  -> i1 INT NOT NULL デフォルト 0,
  -> i2 INT NOT NULL デフォルト 0,
  -> d 日付デフォルト NULL、
  -> 主キー (i1, i2)、
  -> インデックス k_d (d)
  ->) エンジン = InnoDB;

クエリは正常、影響を受けた行は 0 行 (0.14 秒)

テーブル t1 には、列 (​​i1、i2) に定義された主キーがあります。列 (d) にもセカンダリ インデックスが定義されていますが、InnoDB はこのインデックスを拡張し、(d,i1,i2) として扱います。

オプティマイザーは、インデックスの使用方法と使用の有無を決定する際に、拡張セカンダリ インデックスの主キー列を考慮します。これにより、クエリ実行プランの効率が向上し、パフォーマンスが向上します。

オプティマイザーは、ref、range、index_merge インデックス アクセス、ルーズ インデックス スキャン、結合およびソートの最適化、および MIN()/MAX() の最適化に拡張セカンダリ インデックスを使用できます。

次の例は、オプティマイザーが拡張セカンダリ インデックスを使用して実行プランに影響を与え、次のデータをテーブル t1 に挿入するかどうかを示します。

mysql> t1 に値 (1, 1, '1998-01-01')、(1, 2, '1999-01-01')、(1, 3, '2000-01-01')、(1, 4, '2001-01-01') を挿入します。
  ->(1, 5, '2002-01-01')、(2, 1, '1998-01-01')、(2, 2, '1999-01-01')、(2, 3, '2000-01-01')、(2, 4, '2001-01-01')、
  ->(2, 5, '2002-01-01')、(3, 1, '1998-01-01')、(3, 2, '1999-01-01')、(3, 3, '2000-01-01')、(3, 4, '2001-01-01')、
  ->(3, 5, '2002-01-01')、(4, 1, '1998-01-01')、(4, 2, '1999-01-01')、(4, 3, '2000-01-01')、(4, 4, '2001-01-01')、
  ->(4, 5, '2002-01-01')、(5, 1, '1998-01-01')、(5, 2, '1999-01-01')、(5, 3, '2000-01-01')、(5, 4, '2001-01-01')、
  ->(5, 5, '2002-01-01');
クエリは正常、25 行が影響を受けました (0.05 秒)
記録: 25 重複: 0 警告: 0

次のクエリが実行されるとします。

optimizer_switch を 'use_index_extensions=off' に設定します。
i1=3かつd= '2000-01-01'の場合、t1からcount(*)を選択します。

この場合、主キーに列 (i1、i2) が含まれており、クエリが i2 を参照していないため、オプティマイザーは主キーを使用できません。代わりに、オプティマイザは列 (d) のセカンダリ インデックス k_d を使用することができ、実行プランは拡張インデックスが使用されるかどうかによって異なります。

オプティマイザがインデックス拡張を考慮しない場合、インデックスk_dは単に(d)として扱われます。

mysql> SET optimizer_switch = 'use_index_extensions=off';
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

mysql> explain select count(*) from t1 where i1=3 and d= '2000-01-01' \G;
************************** 1. 行 ****************************
      id: 1
 選択タイプ: シンプル
    テーブル: t1
  パーティション: NULL
     タイプ: ref
可能なキー: PRIMARY、k_d
     キー: PRIMARY
   キーの長さ: 4
     参照: 定数
     行数: 5
   フィルター: 20.00
    追加: where の使用
セットに 1 行、警告 1 件 (0.00 秒)

オプティマイザがインデックス拡張を考慮する場合、k_d は (d, i1, i2) であるとみなします。この場合、左端のインデックス プレフィックス (d, i1) を使用して、より適切な実行プランを生成できます。

mysql> SET optimizer_switch = 'use_index_extensions=on';
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

mysql> explain select count(*) from t1 where i1=3 and d= '2000-01-01' \G;
************************** 1. 行 ****************************
      id: 1
 選択タイプ: シンプル
    テーブル: t1
  パーティション: NULL
     タイプ: ref
可能なキー: PRIMARY、k_d
     キー: k_d
   キーの長さ: 8
     参照: const、const
     行数: 1
   フィルター: 100.00
    追加: インデックスの使用
セットに 1 行、警告 1 件 (0.00 秒)

どちらの場合も、 key はオプティマイザーがセカンダリ インデックス k_d を使用することを示していますが、 EXPLAIN 出力には拡張インデックスの使用による次の改善が示されています。

.key_len が 4 バイトから 8 バイトに変更されました。これは、キー検索で d だけでなく列 d と i1 が使用されることを示しています。

キー検索では 1 つのキー列ではなく 2 つのキー列が使用されるため、.ref の値は const から const,const に変わります。

.rows: 5 から 1 に減少し、InnoDB がクエリ結果を生成するために検査する行数が少なくなることを示します。

.Extra 値が、Using where; Using index から Using index に変更されました。つまり、レコードをクエリするには、データ行レコードをクエリするのではなく、インデックスのみを使用する必要があります。

show status を使用すると、拡張インデックスを使用したオプティマイザーと使用しないオプティマイザーの違いを確認できます。

mysql> テーブル t1 をフラッシュします。
クエリは正常、影響を受けた行は 0 行 (0.01 秒)

mysql> ステータスをフラッシュします。
クエリは正常、影響を受けた行は 0 行 (0.03 秒)

上記の flush table および flush status ステートメントは、テーブル キャッシュをクリアし、ステータス統計をクリアするために使用されます。

インデックス拡張を使用しない場合の show status の結果は次のとおりです。

mysql> SET optimizer_switch = 'use_index_extensions=off';
クエリは正常、影響を受けた行は 0 行 (0.01 秒)

mysql> t1 から count(*) を選択します。ここで、i1=3、d= '2000-01-01' です。
+----------+
| カウント(*) |
+----------+
| 1 |
+----------+
セット内の 1 行 (0.00 秒)

mysql> 'handler_read%' のようなステータスを表示します。
+-----------------------+-------+
| 変数名 | 値 |
+-----------------------+-------+
| ハンドラー_read_first | 0 |
| ハンドラー読み取りキー | 1 |
| ハンドラー_read_last | 0 |
| ハンドラー_read_next | 5 |
| ハンドラー_read_prev | 0 |
| ハンドラー読み取り回数 | 0 |
| ハンドラー_read_rnd_next | 0 |
+-----------------------+-------+
セット内の行数は 7 です (0.00 秒)

インデックス拡張を使用すると、show status は次の結果を生成し、handler_read_next の値が 5 から 1 に減少し、このインデックスを使用する方が効率的であることを示します。

mysql> テーブル t1 をフラッシュします。
クエリは正常、影響を受けた行は 0 行 (0.01 秒)

mysql> フラッシュステータス
  -> ;
クエリは正常、影響を受けた行は 0 行 (0.02 秒)

mysql> SET optimizer_switch = 'use_index_extensions=on';
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

mysql> t1 から count(*) を選択します。ここで、i1=3、d= '2000-01-01' です。
+----------+
| カウント(*) |
+----------+
| 1 |
+----------+
セット内の 1 行 (0.00 秒)

mysql> 'handler_read%' のようなステータスを表示します。
+-----------------------+-------+
| 変数名 | 値 |
+-----------------------+-------+
| ハンドラー_read_first | 0 |
| ハンドラー読み取りキー | 1 |
| ハンドラー_read_last | 0 |
| ハンドラー_read_next | 1 |
| ハンドラー_read_prev | 0 |
| ハンドラー読み取り回数 | 0 |
| ハンドラー_read_rnd_next | 0 |
+-----------------------+-------+
セット内の行数は 7 です (0.01 秒)

optimizer_switch システム変数の use_index_extensions フラグを使用すると、オプティマイザは InnoDB テーブルのセカンダリ インデックスの使用方法を決定する際に、プライマリ キー列を考慮から除外できます。デフォルトでは、use_index_extensions は有効になっています。インデックス拡張を無効にするとパフォーマンスが向上するかどうかを確認するには、次のステートメントを実行します。

mysql> SET optimizer_switch = 'use_index_extensions=off';
クエリは正常、影響を受けた行は 0 行 (0.01 秒)

以上がMySQL InnoDBインデックス拡張の詳細な説明です。MySQLインデックス拡張の詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQL InnoDBエンジンのインデックスとストレージ構造の詳細な説明
  • MySQL InnoDBセカンダリインデックスのソート例の詳細な説明
  • MySQL Innodbインデックスの原理の詳細な説明
  • MySQL Innodb インデックス メカニズムの詳細な紹介
  • Mysql Innodb ストレージ エンジン インデックスとアルゴリズム

<<:  Linux zabbix エージェントの展開と設定方法の詳細な説明

>>:  Nginx の動的および静的分離実装ケースのコード分析

推薦する

Linux でマウントされたファイルシステムの種類を表示する方法

序文ご存知のとおり、Linux は ext4、ext3、ext2、sysfs、securityfs、...

MySQL btree インデックスとハッシュ インデックスの違い

MySQL では、ほとんどのインデックス (PRIMARY KEY、UNIQUE、INDEX、FUL...

Oracle の開閉の 4 つのモード

>1 データベースを起動するcmd コマンド ウィンドウで、「sqlplus」を直接入力して ...

npm 淘宝ミラー変更説明

1. トップレベルの使用法1. cnpmをインストールする npm i -g cnpm --regi...

Vue プロジェクトに Electron を追加するための詳細なコード

1. package.jsonに追加する "メイン": "electr...

Vueのフィルターについて知っておくべきこと

目次序文フィルターとは何かフィルターの使い方グローバルフィルターローカルフィルターフィルターは直列に...

Linux deb パッケージの解凍、変更、その他の操作方法のコード例

さまざまな理由により、debパッケージ内のさまざまなファイルの内容を直接変更する必要がある場合があり...

SELINUXの動作原理の詳細な説明

1. はじめにSELinux が Linux にもたらす主な価値は、柔軟で構成可能な MAC メカニ...

音声キューイングシステムを実装するためのJavaScript

目次導入主な特徴エフェクト表示キーコード導入音声キューイングシステムは、銀行、レストラン、病院などの...

CSS で放射状グラデーションを使用してカード効果を実現する

数日前、同僚がポイントモールプロジェクトを受け取りました。このプロジェクトには、カードやクーポンをギ...

IE で ClearType をオンにした後の透明フォントの問題の解決方法

IE で ClearType をオンにした後に発生する透明フォントの問題を解決するには、透明要素に背...

HTMLとは何ですか?

HTML 開発の歴史: HTML は英語で Hypertext Marked Language の...

mysql5.7のインストールとNavicateの長期無料利用の実施手順

(I) mysql5.7のインストール: ❀詳細:無料のグリーンバージョン5.7のインストール方法は...

初心者がHTMLタグを学ぶ(1)

初心者は、いくつかの HTML タグを理解することで HTML を学習できます。この入門書は、初心者...