MySQL InnoDBセカンダリインデックスのソート例の詳細な説明

MySQL InnoDBセカンダリインデックスのソート例の詳細な説明

ソート問題

最近、Geek Time の「45 Lectures on MySQL Practice」を読み、InnoDB セカンダリ インデックスに関する不十分な理解を修正しました。関連する内容を要約する良い機会です。

PS:この記事のすべてのテストは MySQL 8.0.13 に基づいています。

まず質問させてください。次の SQL によって作成されたテーブルには 2 つのクエリ ステートメントがあります。どのインデックスが不要でしょうか。

テーブル `geek` を作成します (
 `a` int(11) NULLではない、
 `b` int(11) NULLではない、
 `c` int(11) NULLではない、
 `d` int(11) NULLではない、
 主キー (`a`,`b`)、
 キー `c` (`c`)、
 キー `ca` (`c`,`a`)、
 キー `cb` (`c`,`b`)
)ENGINE=InnoDB;

c=N で geek から * を選択し、制限 1 で順序付けします。
c=N で geek から * を選択し、b で順序を制限し、1 にします。

著者の答えは、インデックス c と ca のデータ モデルは同じなので、ca は冗長であるというものです。なぜ? ?

セカンダリ インデックスには行の位置ではなくプライマリ キーの値が格納され、インデックスは順序付けられていることもわかっています。

c が ca と同じデータ モデルを持つ場合、セカンダリ インデックスのリーフ ノードは、インデックス列だけでなく、関連付けられているプラ​​イマリ キー値でも並べ替える必要があります。

以前の私の理解では、セカンダリ インデックスはインデックス列によってのみソートされ、プライマリ キーの値はソートされないというものでした。

コラムニストに尋ねたところ、次のような答えが返ってきました。インデックス c は cab (セカンダリ インデックス) のようにソートされ、主キーが含まれ、順序どおりになっていることを確認します。 (追記:これは原文ではありません。3回質問してやっと答えが分かりました)。

まず「かどうか」を問い、次に「なぜ」を問うという考えに基づいて、私たちはいくつかの調査を行いました。

はい、もしくは、いいえ?

InnoDB データファイルを直接表示できる場合は、このソートルールに従っているかどうかを直接確認できます。残念ながらバイナリファイルなので、閲覧するのに便利なツールもないので諦めました。

その後、MyISAM エンジンと InnoDB エンジンの両方のテーブルをサポートする MySQL ハンドラー ステートメントを見つけました。ハンドラー ステートメントは、テーブル ストレージ エンジンに直接アクセスするためのインターフェイスを提供します。

次の構文は、指定されたテーブル内の指定されたインデックスの最初/前/次/最後のレコードを読み取ることを示します。

ハンドラー table_name/table_name_alias は index_name first/pre/next/last を読み取ります。

ハンドラー ステートメントを使用して検証してみましょう。まず、単純なテーブルを作成し、いくつかのデータを挿入します。

テーブル t_simple を作成します (
 id int 主キー、
 v 整数、
 キー k_v (v)
)ENGINE=InnoDB デフォルト文字セット=utf8mb4;

t_simpleに値(1、5)を挿入します。
t_simpleに値(10、5)を挿入します。
t_simpleに値(4、5)を挿入します。

上記の挿入ステートメントでは、セカンダリインデックス列の値は同じであり、プライマリキーの順序が合っていません。このようにして、トラバーサル中にプライマリキーの順序で格納されているかどうかを確認できます。

mysql> ハンドラー t_simple を ts として開きます。
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

mysql> ハンドラ ts 読み取り k_v 次へ;
+----+------+
| id | v |
+----+------+
| 1 | 5 |
+----+------+
セット内の 1 行 (0.00 秒)

mysql> ハンドラ ts 読み取り k_v 次へ;
+----+------+
| id | v |
+----+------+
| 4 | 5 |
+----+------+
セット内の 1 行 (0.00 秒)

mysql> ハンドラ ts 読み取り k_v 次へ;
+----+------+
| id | v |
+----+------+
| 10 | 5 |
+----+------+
セット内の 1 行 (0.00 秒)

結果から、トラバースされたセカンダリインデックスの値が等しい場合、プライマリキーの順序でトラバースしていることがわかります。セカンダリインデックスは、インデックス列だけでなく、プライマリキーの値でもソートされていることを基本的に判断できます。

なぜ?

これまで MySQL でこのようなメカニズムについて言及されているのを見たことがありませんでしたし、以前の会社やその前の会社の DBA もこのことに気づいていませんでした。

最後に、DBA の同僚は、次の説明を含むインデックス拡張を見つけました。

InnoDB は、プライマリ キー列を追加することで、各セカンダリ インデックスを自動的に拡張します。次のテーブル定義を検討してください。

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

InnoDB は各セカンダリ インデックスを自動的に拡張し、プライマリ キー値をインデックス列に追加し、拡張された複合列をインデックスのインデックス列として使用します。上記の t_simple テーブルの k_v インデックスの場合、拡張インデックスは (v, id) 列です。

オプティマイザーは、拡張セカンダリ インデックスの主キー列に基づいて、そのインデックスを使用するかどうか、およびその使用方法を決定します。オプティマイザーは、ref、range、index_merge などのインデックス アクセス タイプ、ルーズ インデックス スキャン、結合およびソートの最適化、min()/max() の最適化に拡張セカンダリ インデックスを使用できます。

インデックス拡張機能が有効になっているかどうかを確認するには、 show variables like '%optimizer_switch%';有効または無効にするにはSET optimizer_switch = 'use_index_extensions=on/off';を使用します。これは現在のセッションにのみ影響します。

テストの結果、現在のセッションのインデックス拡張がオフになっている場合でも、ハンドラーを使用してアクセスすると、主キーによるソートの効果が得られることがわかりました。

要約する

上記はこの記事の全内容です。この記事の内容が皆さんの勉強や仕事に一定の参考学習価値を持つことを願っています。ご質問があれば、メッセージを残してコミュニケーションしてください。123WORDPRESS.COM を応援していただきありがとうございます。

以下もご興味があるかもしれません:
  • MySQLセカンダリインデックスのクエリプロセスを理解するための記事

<<:  VMware15 の CentOS7 インストールの詳細なプロセスとよくある問題 (画像とテキスト)

>>:  JS の 3 つの主要な問題、非同期性とシングルスレッドについて簡単に説明します。

推薦する

React は antd のアップロード コンポーネントを使用してファイル フォーム送信機能を実装します (完全なコード)

私はプロジェクトを実行するために react を使い始めたばかりで、非常に未熟で完全な初心者です。私...

JS ES6コーディング標準の詳細な説明

目次1. ブロックスコープ1.1. let は var を置き換える1.2. グローバル定数とスレッ...

Docker Composeを使用してDOCleverをインストールする詳細なプロセスを説明します

目次1. Docker Composeとは何か、インストールして使用する方法2. DOCleverと...

Apache での ModSecurity のインストール、有効化、および構成

ModSecurity は、Web サーバーに入るすべてのパケットをチェックする強力なパケット フィ...

ネイティブ js カスタム右クリック メニュー

この記事の例では、参考のためにjsカスタム右クリックメニューの具体的なコードを共有しています。具体的...

CSSスタイルのカスケーディングルールの詳細な説明

CSS スタイル ルール構文スタイルは、CSS の基本単位です。各スタイル ルールは、セレクターと宣...

Vue の自動書式設定の改行保存の詳細な説明

ネットで変更方法をいろいろ調べたのですが、うまくいきませんでした。後で大物から見て削除しました。フォ...

nginxでの共有メモリの使用に関する詳細な説明

nginx プロセス モデルでは、トラフィック統計、トラフィック制御、データ共有などのタスクを完了す...

CentOS7にMySQL 8.0.26をインストールする手順

1. まず、お使いのマシンに応じて、MySQL 公式サイトから対応するデータベースをダウンロードしま...

Linux ファイル管理コマンド例の分析 [権限、作成、削除、コピー、移動、検索など]

この記事では、Linux ファイル管理コマンドについて例を挙げて説明します。ご参考までに、詳細は以下...

MySQLグループリンクの使用に関する詳細な説明

MYSQL におけるグループ化とリンクは、データベースの操作やデータのやり取りで最もよく使用される ...

Docker+daocloudはフロントエンドプロジェクトの自動構築とデプロイを実現します

自動プロジェクト展開は大企業やユニコーン企業でよく使用され、手動でプロジェクトを展開するよりも効率的...

Windows10システムにMySQL 5.7.17をインストールする

オペレーティング システム win10 MySQL は、公式 Web サイトからダウンロードした 6...

HTML テーブル マークアップ チュートリアル (28): セルの境界線の色属性 BORDERCOLOR

テーブルを美しくするために、セルごとに異なる境界線の色を設定できます。基本的な構文<TD 境界...

航空機戦争ゲームを実装するためのネイティブJS

この記事の例では、参考のために航空機戦争ゲームを実装するためのJSの具体的なコードを共有しています。...