MySQL インデックスによってクエリ効率が大幅に向上する理由は何ですか?
背景
データベースを最適化するときに、誰もがインデックスについて話すと思いますが、私も例外ではありません。データ構造の最適化については、基本的に誰もが 1 つの質問に答えることができます。 1 つか 3 つ、ページ キャッシュなどについては、少し話せますが、あるとき Alibaba P9 の面接官が私にこう尋ねました。「コンピューター レベルからインデックス データをロードするプロセスについて話してもらえますか?」 (IO について話してほしかっただけです)
私はその場で死にました。コンピューター ネットワークとオペレーティング システムの基本的な知識は私の盲点だったのですが、後で補ったので、ナンセンスな話はしません。コンピューターがデータをロードするところから始めて、インデックス作成について別の角度から話しましょう。
本文
MySQL のインデックスは本質的にデータ構造です
まず、コンピューターへのデータの読み込みについて理解しましょう。
ディスク IO と事前読み取り:

まずはディスク IO について説明します。ディスクのデータ読み取りは機械的な動作に依存します。データを一度に取得するには、シーク、ポイントの検索、メモリへのコピーという 3 つのステップが必要です。
シーク時間は磁気アームが指定されたトラックに移動するのに必要な時間で、通常は 5ms 未満です。
サーチ ポイントはトラックからデータが存在するポイントを見つけるまでの平均時間は半回転、7200 rpm のディスクの場合、ポイントを見つけるまでの平均時間は 600000/7200/2=4.17ms;
メモリへのコピー 時間は非常に高速ですが、前の 2 回と比較すると無視できるほどであるため、1 回の IO の平均時間は約 9ms です。速いように思えますが、データベース内の数百万のデータを処理するには 9000 秒かかります。これは明らかに災害レベルです。


もメモリ バッファに読み込まれます。これは、コンピュータがあるアドレスのデータにアクセスすると、そのデータはそのアドレスに隣接するためです。データへのアクセスも迅速になります。 毎回 IO によって読み取られるデータをページと呼びます。ページ上のデータの具体的なサイズはオペレーティング システムによって異なります。通常は 4k または 8k です。つまり、1 ページでデータを読み取ります。この時点で、実際に発生した IO は 1 回だけでした。
(卒業直後に私が尋ねられた質問を突然思い出しました。64 ビット オペレーティング システムでは、Java の int 型は何バイトを占めますか?最大値はいくらですか?なぜですか?)
データベース クエリを最適化したい場合は、
ディスク IO 操作を可能な限り削減する必要があります。そうすれば、インデックスが表示されます。 インデックスとは何ですか?
MySQLインデックスの正式な定義は次のとおりです。インデックス (インデックス) は、MySQL
がデータを効率的に取得するのに役立つデータ構造です。
一般的に使用されるインデックスは、B ツリー インデックスとハッシュ インデックスの 2 つのカテゴリに物理的に分類されます。 今回は主に
インデックスについてお話します。 BTree インデックス
マルチパスバランスドサーチツリーとも呼ばれ、m-fork BTree の特徴は次のとおりです。 #ツリー内の各ノード ノードには最大 m 個の子が含まれます。
- ルート ノードがリーフ ノードでない場合、ルート ノードには少なくとも 2 つの子があります。
- すべてのリーフ ノードは同じレイヤー上にあります。
- 各非リーフ ノードは、n 個のキーと n 1 個のポインターで構成されます ([ceil(m/2)-1]

1. ルート ノード ポインタに従って、ファイル ディレクトリのルート ディスク ブロック 1 を読み取ります。 [ディスク IO 操作
1 回]
2. ディスク ブロック 1 には、17、35、および 3 つのポインター データが格納されます。 173. p2 ポインタに従って、ディスク ブロック 3 を見つけて読み取ります。 [ディスク IO 操作
2 回]
4. ディスク ブロック 3 には、26、30、および 3 ポインター データが格納されます。 26
5. p2 ポインタに従って、ディスク ブロック 8 を見つけて読み取ります。 [ディスク IO 操作 3 回 ]
6、ディスク ブロック 8 には 28、29 が格納されます。 29 を見つけて、29 に対応するデータを取得します。
BTree インデックスにより、メモリからフェッチされたデータが各ディスク I/O で役割を果たし、クエリ効率が向上することがわかります。
しかし、最適化できることはあるのでしょうか?
この図から、各ノードにはデータのキー値だけでなくデータ値も含まれていることがわかります。各ページの記憶容量は限られており、データデータが大きい場合、各ノード (つまり 1 ページ) に保存できるキーの数は非常に少なくなります。 to B- ツリーの深さが大きくなり、クエリ中のディスク I/O の数が増加し、クエリの効率に影響します。
B Tree Index
B Tree
は B-Tree
に基づいた最適化であり、外部ストレージ インデックス構造の実装により適しています。 B Treeでは、すべてのデータレコードノードがキー値順に同じ階層のリーフノードに格納され、非リーフノードにはキー値情報のみが格納されるため、各ノードに格納されるキー値の数を大幅に増やすことができます。 . B ツリーの高さを下げます。

B ツリーには、B ツリーと比較していくつかの違いがあります。
非リーフ ノードは、キー値情報、データ レコードのみを保存します。前節で B ツリーを最適化すると、B ツリーの非リーフ ノードにはキー値情報のみが格納されるため、B ツリーの高さを特に低いレベルに圧縮できます。
具体的なデータは次のとおりです:
InnoDB ストレージ エンジンのページ サイズは 16KB、一般テーブルの主キーのタイプは INT (4 バイトを占有) または BIGINT です(8 バイトを占有します。バイト)、ポインタ タイプは通常 4 または 8 バイトです。これは、1 つのページ (B ツリーのノード) に約 16KB/(8B 8B)=1K のキー値が格納されることを意味します (計算の便宜上、ここでの K の値は 〖10〗^3) とします。
つまり、深さ 3 の B ツリー インデックスは 10^3 10^3 10^3 = 10 億レコードを維持できます。 (この計算方法にはエラーがあり、リーフ ノードは計算されません。リーフ ノードが計算される場合、実際の深さは 4 になります。)
データを抽出するために必要な IO 操作は 3 回だけです。必要なデータを見つけるには、9,000 秒の最初の 100 万個のデータよりも何倍優れているかわかりません。
そして通常、B ツリーには 2 つのヘッド ポインターがあり、1 つはルート ノードを指し、もう 1 つは最小のキーを持つリーフ ノードを指し、すべてのリーフ ノード間にはチェーン リング構造があります (つまり、データノード) 。そのため、B Treeでは主キー範囲検索やページング検索に加えて、ルートノードからのランダム検索も行うことができます。
データベースの B ツリー インデックスは、クラスター化インデックスとセカンダリ インデックスに分けることができます。
上記の B ツリーの例の図のデータベースへの実装はクラスター化インデックスです。クラスター化インデックスの B ツリーのリーフ ノードにはテーブル全体の行レコード データが格納されます。補助インデックスとの違いは次のとおりです。補助インデックスのリーフ ノードには、行レコードのすべてのデータが含まれるのではなく、対応する行データを格納するクラスター化インデックス キー、つまり主キーが含まれます。
補助インデックスを通じてデータをクエリする場合、InnoDB ストレージ エンジンは補助インデックスを走査して主キーを見つけ、主キーを通じてクラスター化インデックス内の完全な行レコード データを見つけます。

ただし、インデックスを使用するとクエリが高速化され、MySQL の処理パフォーマンスが向上しますが、インデックスを過度に使用すると、次の 欠点 :
- インデックスの作成と維持には時間がかかり、データ量が増えるとこの時間も長くなります。
- データ テーブルが占有するデータ領域に加えて、各インデックスも一定量の物理領域を占有します。クラスター化インデックスを作成する場合、必要なスペースはさらに大きくなります。
- テーブル内のデータを追加、削除、変更する場合、インデックスも動的に維持する必要があるため、データのメンテナンス速度が低下します。
注: インデックスを使用するとクエリを高速化できる場合もありますが、効率が低下する場合もあります。
インデックスは効率を向上させるための 1 つの要素にすぎないため、インデックスを作成するときは次の原則に従う必要があります。
- 頻繁に検索される列にインデックスを作成すると、検索を高速化できます。
- 列を主キーとしてインデックスを作成し、列の一意性を確保し、テーブル内のデータの配置構造を整理します。
- テーブル接続に頻繁に使用される列にインデックスを作成します。これらの列は主に外部キーであり、テーブル接続を高速化できます。
- 範囲に基づいて検索する必要が多い列にインデックスを作成します。インデックスは並べ替えられているため、指定された範囲は連続しています。
- 頻繁に並べ替えが必要な列にインデックスを作成します。インデックスは並べ替えられているため、インデックスの並べ替えを使用してクエリの並べ替えを高速化できます。
- WHERE句を頻繁に使用する列にインデックスを作成し、条件の判定を高速化します。
これで、インデックスがこれほど高速になる理由が誰でもわかりました。実際、これはほんの 1 文です。インデックス構造により、データベースの IO 回数を最小限に抑えることができます。結局のところ、1 回の時間はIO は本当に長すぎます。 。 。
まとめ
面接に関して言えば、実際には多くの知識を簡単に習得できますが、学習目的であれば、多くの知識が必要であることがわかります。 「それを発見するには、コンピュータの基礎を深く掘り下げる必要があります。不思議なことに、どうしてそんなにたくさんのことを覚えているのかとよく聞かれます。実際、学ぶこと自体はとても無力なことです。学ばなければならないのですから、なぜ一生懸命学ばないのでしょうか?」楽しむことを学ぶには?最近は基礎の勉強もしているので、これからパソコンの基礎やネットワーク関連の知識も更新していこうと思います。
私は Ao Bing です。知れば知るほど、知らないことが増えます。次号でお会いしましょう!
タレント 私たちの 【三连】 が Ao Bing の創作の最大の動機です。このブログに間違いや提案がある場合は、タレントの方はコメントを残してください。メッセージ!
#その他の関連する無料学習の推奨事項: mysql チュートリアル(ビデオ)
以上がMySQL インデックスによってクエリ効率が大幅に向上する理由は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









一般的な状況: 1. 関数または演算を使用する; 2. 暗黙的な型変換; 3. 等しくない (!= または <>) を使用する; 4. LIKE 演算子を使用し、ワイルドカードで始める; 5. OR 条件; 6. NULL値、7. 低いインデックス選択性、8. 複合インデックスの左端の接頭辞の原則、9. オプティマイザーの決定、10. FORCE INDEX および IGNORE INDEX。

MySQL インデックスは、インデックス カラムを使用せずにクエリを実行した場合、データ型が一致していない場合、プレフィックス インデックスが不適切に使用された場合、クエリに関数や式を使用した場合、インデックス カラムの順序が正しくない場合、データ更新が頻繁に行われる場合、インデックスが多すぎるか少なすぎる場合に失敗します。 1. クエリにはインデックス列を使用しないでください。この状況を回避するには、クエリで適切なインデックス列を使用する必要があります。2. データ型が一致しません。テーブル構造を設計するときは、インデックス列がクエリの構造と一致していることを確認する必要があります。クエリのデータ型; 3. 、プレフィックス インデックスの不適切な使用、プレフィックス インデックスを使用できます。

MySQL インデックスの左端の原則とコード例 MySQL では、インデックス作成はクエリ効率を向上させる重要な手段の 1 つです。その中でも、インデックスの左端の原則は、インデックスを使用してクエリを最適化するときに従う必要がある重要な原則です。この記事では、MySQL インデックスの左端の原則を紹介し、具体的なコード例をいくつか示します。 1. インデクス左端原則の原則 インデクス左端原則とは、インデクスにおいて問合せ条件が複数の列で構成される場合、問合せ条件を完全に満たすにはインデクスの左端の列のみを問合せできることを意味します。

MySQL インデックスは次のタイプに分類されます: 1. 通常のインデックス: 値、範囲、またはプレフィックスに一致します。 2. 固有のインデックス: 値が一意であることを確認します。 3. 主キー インデックス: 主キー列の一意のインデックス。キー インデックス: 別のテーブルの主キーを指します。 5. フルテキスト インデックス: 全文検索。 7. 空間インデックス: 地理空間検索。列。

MySQLは、Bツリー、ハッシュ、フルテキスト、および空間の4つのインデックスタイプをサポートしています。 1.B-Treeインデックスは、等しい値検索、範囲クエリ、ソートに適しています。 2。ハッシュインデックスは、等しい値検索に適していますが、範囲のクエリとソートをサポートしていません。 3.フルテキストインデックスは、フルテキスト検索に使用され、大量のテキストデータの処理に適しています。 4.空間インデックスは、地理空間データクエリに使用され、GISアプリケーションに適しています。

PHP および MySQL インデックスのデータ更新とインデックス保守のためのパフォーマンス最適化戦略と、それらがパフォーマンスに与える影響 概要: PHP および MySQL の開発において、インデックスはデータベース クエリのパフォーマンスを最適化するための重要なツールです。この記事では、インデックスの基本原則と使用法を紹介し、データの更新とメンテナンスに対するインデックスのパフォーマンスへの影響を検討します。同時に、この記事では、開発者がインデックスをよりよく理解して適用できるように、いくつかのパフォーマンス最適化戦略と具体的なコード例も提供します。インデックスの基本原則と使用法 MySQL では、インデックスは特別な番号です。

MySQL インデックスを合理的に使用し、データベースのパフォーマンスを最適化するにはどうすればよいでしょうか?技術系の学生が知っておくべき設計プロトコル!はじめに: 今日のインターネット時代では、データ量は増加し続けており、データベースのパフォーマンスの最適化が非常に重要なテーマになっています。最も人気のあるリレーショナル データベースの 1 つである MySQL では、データベースのパフォーマンスを向上させるためにインデックスを合理的に使用することが重要です。この記事では、MySQL インデックスを合理的に使用し、データベースのパフォーマンスを最適化し、技術系の学生向けにいくつかの設計ルールを提供する方法を紹介します。 1. なぜインデックスを使用するのでしょうか?インデックスは、以下を使用するデータ構造です。

タイトル: データの一意性を確保するために MySQL で一意のインデックスを作成する方法とコード例 データベース設計では、データの一意性を確保することが非常に重要です。これは、MySQL で一意のインデックスを作成することで実現できます。一意のインデックスを使用すると、テーブル内の特定の列 (または列の組み合わせ) の値が一意であることが保証されます。重複する値を挿入しようとすると、MySQL はこの操作を阻止し、エラーを報告します。この記事では、MySQL で一意のインデックスを作成する方法を、具体的なコード例を示しながら紹介します。一意のインデックスとは何ですか? 一意のインデックスは、インデックスの一種です。
