インデックス拡張: 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の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
<<: Linux zabbix エージェントの展開と設定方法の詳細な説明
>>: Nginx の動的および静的分離実装ケースのコード分析
1. カラーマッチング効果のプレビュー下の GIF に示すように、ボタンの背景色が徐々に薄くなると...
以前、純粋な CSS を使用して波の効果を実現する方法をいくつか紹介しました。それらについては、次の...
marquee タグを使用してフォントのスクロールを設定したいです。コードは次のように記述しましたが...
タブバー: 異なるタブをクリックすると異なるコンテンツが表示され、クリックしたタブのスタイルが変更さ...
目次CentOS 8にDockerをインストールする1. yumを更新する2. containerd...
高性能で軽量なウェブサービスソフトウェアであるNginxについて高い安定性 システムリソースの消費量...
背景go-fastdfs は、http プロトコルをサポートする分散ファイルシステムです。一般的なプ...
rpmインストールパッケージをダウンロードするMySQL公式サイト: https://dev.mys...
序文vue3 を使った例をいくつか書いてみましたが、Vue3 のコンポジション API はよく設計さ...
目次1. 古いMySQL5.7データをバックアップする2. MySQL8.0.13のイメージをプルし...
mysql は期間内のすべての日付または月を取得します1: mysqlは期間内のすべての月を取得し...
1. 前提条件インポートには require.context メソッドを使用します。vite で作成...
目次1. ユニットテストはなぜ必要なのでしょうか? 2. ユニットテストの書き方3. テストツール4...
目次Vue でのスロットの使用: slotスコープ付きスロット: テンプレートタグで囲む要約するVu...
序文前回の面接では、実行計画について質問されたとき、多くの人がそれが何なのか知りませんでした。実行計...