MySQL インデックス プッシュダウンの詳細

MySQL インデックス プッシュダウンの詳細

序文:

インデックス プッシュダウン (ICP) は、MySQL がインデックスを使用してテーブルから行を取得する状況に対する最適化です。

  • インデックス プッシュダウンがない場合、MySQL はストレージ エンジンを使用してインデックスをトラバースし、テーブル内のデータ行を見つけて MySQL サーバーに返します。次に、サーバーは WHERE 条件を決定して、データ行を結果セットに追加するかどうかを確認します。
  • インデックス プッシュダウンが有効になっていて、WHERE 条件の一部をインデックス内の列のみを使用して評価できる場合、MySQL サーバーは WHERE 条件のこの部分をストレージ エンジンにプッシュします。ストレージ エンジンは、インデックス エントリを使用してプッシュされたインデックス条件を評価し、条件が満たされた場合にのみテーブルから読み取ります。

インデックス プッシュダウンにより、ストレージ エンジンがデータ テーブルにアクセスする回数と、MySQL サーバーがストレージ エンジンにアクセスする回数を削減できます。

まだ少し混乱していますか?その通りです。上記の段落は確かに理解するのがかなり難しいですが、落胆しないでください。最もわかりやすい言葉を使って、インデックス プッシュダウンを理解する方法を説明します。

要約すると:

  • 左端接頭辞原則
  • 表に戻る

1. 左端接頭辞原則

MySQL 、結合インデックスを確立するときに、最左接頭辞の原則に従います。たとえば、User テーブルには結合インデックス (id、name、age) が確立されます。最左接頭辞の原則によると、この結合インデックスは、SQL の条件部分が (id)、(id、name)、または ( idnameage ) に一致する場合にのみ使用できます。

インデックスは次の状況で使用できます。

SELECT * FROM USER WHERE id = 1

SELECT * FROM USER WHERE id = 1 かつ name = 'zhangsan'

SELECT * FROM USER WHERE id = 1、name = 'zhangsan'、age = 18 の場合

次の状況ではインデックスは使用できません。

SELECT * FROM USER WHERE name = 'zhangsan'

SELECT * FROM USER WHERE age = 18

SELECT * FROM USER WHERE name = 'zhangsan'、age = 18 の場合

結合インデックスの場合、 mysql範囲クエリ (>、<、 betweenlike ) に遭遇して一致を停止するまで、右方向への一致処理を続けます。

2. 表に戻る

MySQLInnoDBエンジンで 2 種類のインデックスをサポートしています。

  • クラスター化インデックス:インデックス (B+ ツリーのリーフ ノード上) はデータ行 (実データ) を格納します。
  • 通常のインデックス:主キーはインデックスに格納されます (B+ ツリーのリーフ ノード上)

ここではクラスター化インデックスに焦点を当てます。公式ドキュメントには次のように説明されています。

  • InnoDB 、主キーを持つテーブルのクラスター化インデックスとして主キーを使用します。
  • 主キーのないテーブルの場合、 InnoDB最初の一意のインデックスをクラスター化インデックスとして使用します。
  • 主キーまたは一意のインデックスがない場合、MySQL はクラスター化インデックスとして非表示の 6 バイトrow IDフィールドを生成します。

MySQL通常のインデックスを通じて一度にすべてのデータを取得できない場合、通常のインデックスを通じて主キー値を取得し、主キー値を通じてクラスター化インデックス内のレコードを検索します。このプロセスはテーブル取得と呼ばれます。カバリングインデックスを作成することで、テーブルを返す回数を減らすことができます。たとえば、ID番号で名前を検索する場合、ID番号と名前の結合インデックス( idname )を作成できます。クエリを実行すると、このインデックスを通じてnameの値を直接取得でき、クラスター化インデックスで検索する必要がなくなります。これがカバリングインデックスです。

3. インデックスプッシュダウン

まずユーザーテーブルを作成する

テーブル「学生」を作成(
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) デフォルト NULL,
  `age` int デフォルト 0,
  `class` varchar(255) デフォルト NULL,
  主キー (`id`)、
  キー `index_two` (`name`,`age`)
)ENGINE=InnoDB;

//このテーブルに複合インデックス (`name`,`age`) を追加します

テーブルにデータを挿入する

`student` (`name`, `age`, `class`) に VALUES ('pengpeng', 21, '1') を挿入します。
`student` (`name`, `age`, `class`) に VALUES ('pengpeng', 22, '2') を挿入します。
`student` (`name`, `age`, `class`) に VALUES ('pengpeng', 23, '3') を挿入します。
`student` (`name`, `age`, `class`) に VALUES ('pengpeng', 24, '4') を挿入します。
`student` (`name`, `age`, `class`) に VALUES ('pengpeng', 25, '5') を挿入します。


クエリによって挿入されたデータは次のとおりです

次に次のSQLを説明します

説明: select * from student where name like 'peng%' and age = 23;


Extra フィールドに USING INDEX CONDITION と表示されていることがわかります。これは、この SQL がインデックス プッシュダウンを使用していることを示しています。上記の SQL ステートメントを分析してみましょう。

MySQL 5.6 より前では、名前フィールドから条件を満たす行のみを検索し、テーブルに戻ってクラスター化インデックスのデータ行を検索し、年齢フィールドを比較して、条件に該当するデータを結果セットに追加することしかできませんでした。

インデックス プッシュダウン最適化は、MySQL 5.6 で導入されました。インデックス トラバーサル プロセス中に、インデックスに含まれるフィールドが最初に判断されます。ここでは、age フィールドが判断されます。年齢フィールドの要件を満たさないデータ行を直接除外することで、テーブルから返される値の数を減らします。

質疑応答エリア

質問 1:複合インデックス列が (名前、年齢、住所) の場合、次の SQL でインデックスを使用できますか?

名前が 'peng%' で、年齢が 23 である学生から * を選択します。


はい、like に遭遇すると後続の要素のマッチングが中断されますが、使用できるのは name フィールドのみです。MySQL は範囲クエリ (>、<、between、like) に遭遇してマッチングを停止するまで、右側へのマッチングを続けます。範囲列ではインデックスを使用できますが、範囲列に続く列ではインデックスを使用できません。つまり、インデックスは最大 1 つの範囲列に使用されるため、クエリ条件に 2 つの範囲列がある場合、インデックスを完全に使用することはできません。

質問 2:インデックス プッシュダウンは、結合インデックスにのみ存在できますか?

はい、非結合インデックスではインデックス プッシュダウンは不可能です。

質問 3:どのような状況でインデックス プッシュダウンを使用できないのでしょうか?

プッシュダウン条件がサブクエリに遭遇しました

押し下げ条件遭遇機能

非 InnoDB テーブルと MyISAM テーブル

質問 4 : インデックス プッシュダウンをオン/オフにするにはどうすればいいですか?

// インデックスプッシュダウンはデフォルトで有効になっています。set optimizer_switch='index_condition_pushdown=off'; // 無効にする set optimizer_switch='index_condition_pushdown=on'; // 有効にする

要約する

非主キー インデックスのインデックス プッシュダウンの最適化により、テーブル リターンの数を効果的に削減し、クエリの効率を大幅に向上できます。日常業務では、インデックス プッシュダウンを使用して、ビジネス状況に応じてインデックスを最適化し、ビジネス スループットを向上させることができます。

これで、MySQL インデックス プッシュダウンに関する詳細な記事は終了です。MySQL インデックス プッシュダウンに関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQL インデックス データ構造の詳細な分析
  • MySQLデータベースのトランザクションとインデックスの詳細な説明
  • MySQLはインデックスプッシュダウンを数秒で理解するのに役立ちます
  • MySQL インデックス プッシュダウンを 5 分で理解する
  • MySQL Index Pushdown (ICP) とは何かを理解するための記事
  • MySQL 面接の質問: ハッシュ インデックスの設定方法

<<:  CSSはBEM命名規則の実践を使用する

>>:  CSS の優先順位に関する詳細な紹介

推薦する

10秒以内にMySQLデータベースに数百万件のレコードを挿入する実装

まず、次の質問について考えてみましょう。このような膨大な量のデータをデータベースに挿入するには、通常...

跳ねるボールを実現するネイティブjs

思いつきで、小さなボールが跳ね返るケーススタディを書いてみました。具体的な内容は以下のとおりです。主...

CSS と JavaScript を使用して管理ダッシュボードのレイアウトを構築するためのサンプル コード

あなたが作成するものこの新しいチュートリアルでは、CSS と JavaScript を使用して、レス...

WeChatアプレットのオーディオコンポーネントがiOSで再生できない問題の解決策

解決策:クリック イベントをオーディオ コンポーネントにバインドし、再生メソッドと一時停止メソッドを...

Dockerコンテナのデータボリュームの詳細な説明

何ですかまず、Docker の概念を見てみましょう。アプリケーションと実行環境をコンテナにパッケージ...

MySql でメモリ使用量を削減する方法の詳細な説明

序文デフォルトでは、MySQL はデータベース クエリ データをキャッシュするために大きなメモリ ブ...

Docker-Composeコマンドの使い方の詳しい説明

Docker コンテナはさまざまな方法で管理およびデプロイできます。 Docker コマンドを直接使...

Nginx SSL証明書設定エラーの解決策

1. はじめにWeb プロジェクトを Linux サーバーで公開する場合、SSL 証明書を構成する必...

Tomcatの動作原理を分析する

SpringBoot は巨大な Python のようで、ゆっくりと私たちの周りを巻きつき、麻痺させま...

JavaScriptタイマーの詳細な説明

目次簡単な紹介間隔の設定説明するパラメータ戻り値使用法タイムアウトの設定説明するパラメータ使用法:タ...

CSS 線形グラデーション凹型長方形遷移効果の実装

この記事では、線形グラデーションの凹四角形の遷移効果の難しさやアイデアについて説明します。主に、凹四...

CSS スティッキーフッター実装コード

この記事では、CSS スティッキー フッターの実装コードを紹介し、共有します。詳細は次のとおりです。...

フロントエンド開発者に何百万ドルもの価値をもたらす 10 のスキル

フロントエンド開発者が習得する必要のあるスキル。これらのスキルにより、フロントエンド開発者の価値は数...

js を使用して 2 つの HTML ウィンドウ間で通信する方法

シナリオ: ページAがページBを開くと、ページBで操作した後、ページAは変更されたデータを同期する必...

MySQL の frm ファイルからテーブル構造を復元する 3 つの方法 [推奨]

mysql が正常に実行されている場合、テーブル構造を表示することは難しくありません。しかし、場合...