1. インデックスの基礎知識1.1 インデックスの利点
1.2 インデックスの有用性
1.3 インデックスの分類データベースはデフォルトでインデックスを作成しますが、主キーは一意であり空ではないため、主キーに対してではなく、一意キーに対してインデックスを作成します。
たとえば、このインデックスは、id、name、age の 3 つのフィールドで構成されています。インデックス行は、id/name/age の順序で保存されます。インデックスは、(id、name、age)、(id、name)、または (id) のフィールドの組み合わせをインデックス化できます。クエリ対象のフィールドがインデックスの左端のプレフィックスを構成していない場合、インデックスは使用されません。たとえば、年齢または (名前、年齢) の組み合わせは、インデックスを使用してクエリされません。 1.4 インタビューの専門用語テーブル リターン: データベースは、インデックス (主キーではない) に基づいて指定されたレコードが配置されている行を見つけた後、主キーに基づいてデータ ブロックから再度データを取得する必要があります。これをテーブル リターンと呼びます。 カバーインデックス: 私が書いた記事を読む: SQL の質問で 3 つの面接に落ちた - SQL パフォーマンスの最適化 左端の一致: 結合インデックスでは、SQL ステートメントが結合インデックスの左端のインデックスを使用する場合、この SQL ステートメントはこの結合インデックスを一致に使用できます。範囲クエリ (>、<、between、like) が検出されると、一致は停止します。 select * from t where a=1 and b=1 and c =1; #このようにして、定義されたインデックス (a,b,c) を使用し、a,b,c を使用することができます。 select * from t where a=1 and b=1; #このようにして、定義されたインデックス(a,b,c)を使用してa,bを使用することができます。 select * from t where b=1 and a=1; #このようにして、定義されたインデックス (a, b, c) を使用し、a と c を使用できます (MySQL にはクエリ オプティマイザがあります) select * from t where a=1; #このようにして、定義されたインデックス(a, b, c)を使用することもできます。 select * from t where b=1 and c=1; #定義されたインデックス (a, b, c) は使用できません select * from t where a=1 and c=1; #この方法では、定義されたインデックス (a、b、c) を使用できますが、インデックス a のみが使用され、インデックス b と c は使用されません。 インデックス プッシュダウン: インデックス コンディション プッシュダウン (ICP) とも呼ばれるこの方法は、MySQL が提供する方法で、特定のインデックスを使用して特定のテーブルからタプルを取得します。ここでは意図的に「1」を強調していることに注意してください。これは、このようなインデックス最適化は、複数のテーブル接続ではなく、単一のテーブル スキャンに使用されるためです。正確には、インデックスを使用して単一のテーブルをスキャンしてデータを取得する方法です。 1.5 インデックスで使用されるデータ構造1.5.1 ハッシュテーブル欠点︰ 1. ハッシュ ストレージを使用する場合、すべてのデータ ファイルをメモリに追加する必要があり、より多くのメモリ領域が消費されます。 2. すべてのクエリが等値クエリである場合、ハッシュは確かに非常に高速です。ただし、企業や実際の作業環境では、等値クエリではなく、範囲内でより多くのデータが検索されるため、ハッシュはあまり適していません。 1.5.2 二分木デメリット: バイナリツリーでも赤黒ツリーでも、ツリーの深さによって IO 操作の数が増え、データ読み取りの効率に影響します。 1.5.3 B+ツリーBツリーの機能: 1. すべてのキー値がツリー全体に分散されている 2. 検索はリーフノード以外で終了する可能性があり、キーワードセット全体で検索が実行され、バイナリ検索に近いパフォーマンスが得られます。 3. 各ノードは最大でm個のサブツリーを持つ 4. ルートノードには少なくとも2つのサブツリーがある 5. ブランチノードには少なくともm/2個のサブツリーがあります(ルートノードとリーフノードを除くすべてのノードはブランチノードです) 6. すべてのリーフノードは同じレイヤーにあり、各ノードは最大でm-1個のキーを持つことができ、昇順に並べられます。 例の図の説明: 各ノードはディスク ブロックを占有します。ノードには 2 つの昇順のキーワードと、サブツリーのルート ノードへの 3 つのポインタがあります。ポインタには、子ノードが配置されているディスク ブロックのアドレスが格納されます。 2 つのキーワードによって分割された 3 つの範囲ドメインは、3 つのポインタによって指されるサブツリーのデータの範囲ドメインに対応します。ルートノードを例にとると、キーワードは 16 と 34 であり、P1 ポインタが指すサブツリーのデータ範囲は 16 未満、P2 ポインタが指すサブツリーのデータ範囲は 16 ~ 34、P3 ポインタが指すサブツリーのデータ範囲は 34 より大きいです。 キーワード検索プロセス:
欠点:
1.6 インデックスマッチング法完全な値の一致: 完全な値の一致とは、インデックス内のすべての列が一致することを指します。 select * from staffs where name = 'July' and age = '23' and pos = 'dev'; を説明します。 左端のプレフィックスに一致: 最初の数列のみに一致 select * from staffs where name = 'July' and age = '23'; を説明します。 select * from staffs where name = 'July'; を説明します。 列プレフィックスの一致: 列値の先頭を一致させることができます。 select * from staffs where name like 'J%'; を説明します。 select * from staffs where name like '%y'; を説明します。 一致範囲値: 特定の範囲内のデータを検索できます。 説明 select * from staffs where name > 'Mary'; 列と範囲の一致は完全に一致し、別の列と一致します。最初の列全体と2番目の列の一部を照会できます。 名前が 'July' かつ年齢が 25 を超える staffs から * を選択します。 インデックスのみのクエリ: クエリを実行するときは、インデックスのみにアクセスすればよく、データ行にアクセスする必要はありません。これは基本的にカバーリング インデックスです。 説明 select name,age,pos from staffs where name = 'July' and age = 25 and pos = 'dev'; 2. ハッシュインデックスハッシュテーブルの実装に基づいて、インデックスのすべての列に正確に一致するクエリのみが有効になります。 MySQL では、メモリ ストレージ エンジンのみがハッシュ インデックスを明示的にサポートします。 ハッシュ インデックス自体は対応するハッシュ値のみを格納する必要があるため、インデックス構造は非常にコンパクトになり、ハッシュ インデックスの検索が非常に高速になります。 2.1 ハッシュインデックスの制限
2.2 例多数の URL を保存し、 このクエリは、検索を完了するために非常に小さなインデックスを使用するため、パフォーマンスが高くなります。 3. 総合指数複数の列をインデックスとして含める場合、正しい順序はインデックスのクエリによって異なることに注意することが重要であり、並べ替えやグループ化のニーズをより適切に満たす方法も考慮する必要があります。 例: 複合インデックス a、b、c を作成し、異なる SQL ステートメントでそのインデックスを使用する
4. クラスター化インデックスと非クラスター化インデックス4.1 クラスター化インデックスこれは個別のインデックス タイプではなく、データ ストレージ方式であり、データ行と隣接するキー値がコンパクトにまとめて格納され、データ ストレージとインデックスが一緒に配置されます。インデックスを検索すると、データも検索されます。 主キーが定義されていない場合、InnoDB は代わりに一意の空でないインデックスを選択します。一意のインデックスがない場合、InnoDB は暗黙的に主キーをクラスター化インデックスとして定義します。 InnoDB は同じページ内のレコードのみをクラスター化します。隣接するキー値を含むページは離れている場合があります。 4.2 非クラスター化インデックスデータファイルはインデックスファイルとは別に保存され、データはインデックスとは別の構造に保存されます。インデックス構造のリーフノードは、データの対応する行を指します。MyISAM は、key_buffer を介してインデックスをメモリにキャッシュします。データにアクセスする必要がある場合 (インデックスを介してアクセスする場合)、メモリ内でインデックスを直接検索し、次にインデックスを介してディスク上の対応するデータを見つけます。これが、インデックスがキーバッファにヒットしない場合に速度が遅くなる理由です。 データページ内のデータはリーフノードポインターを介して検索されるため、非クラスター化インデックスは論理的な順序になっています。 5. カバーインデックス5.1 基本的な紹介
5.2 利点1. インデックス エントリは通常、データ行のサイズよりもはるかに小さくなります。インデックスの読み取りのみが必要な場合、MySQL はデータ アクセスの量を大幅に削減します。 2. インデックスは列の値の順序で保存されるため、IO 集中型の範囲クエリの IO は、ディスクから各データ行をランダムに読み取る場合よりもはるかに少なくなります。 3. MYISAM などの一部のストレージ エンジンは、インデックスをメモリにキャッシュするだけで、データのキャッシュはオペレーティング システムに依存します。そのため、データにアクセスするにはシステム コールが必要になり、重大なパフォーマンスの問題が発生する可能性があります。 4. カバーリングインデックスは、INNODBのクラスター化インデックスのため、INNODBテーブルに特に役立ちます。 5.3 ケースデモンストレーション1. インデックスでカバーされたクエリが開始されると、使用しているインデックスの情報がexplainの追加列に表示され、この時点でカバーするインデックスが使用されます。 2. ほとんどのストレージ エンジンでは、カバー インデックスは、インデックス内の一部の列のみにアクセスするクエリのみをカバーできます。ただし、InnoDB のセカンダリ インデックスを使用してクエリをカバーすることで、さらに最適化を実行できます。 たとえば、actor は Innodb ストレージ エンジンを使用し、last_name フィールドにセカンダリ インデックスを持っています。このインデックスの列には主キー actor_id は含まれていませんが、actor_id に対してカバーリング クエリを実行するために使用することもできます。 6. 細部を最適化するクエリにインデックス列を使用する場合は、式を使用せず、計算をデータベース レイヤーではなくビジネス レイヤーに配置するようにしてください。 主キー クエリはテーブル クエリをトリガーしないため、他のインデックスの代わりに主キー クエリを使用するようにしてください。 プレフィックスインデックスの使用 > 非常に長い文字列をインデックスする必要があり、インデックスが大きく遅くなる場合があります。通常、列の先頭に部分的な文字列を使用すると、インデックススペースが大幅に節約され、インデックスの効率が向上します。ただし、これによりインデックスの選択性が低下します。インデックスの選択性とは、データテーブル内のレコードの総数に対する非重複インデックス値の比率を指し、1/#Tから1の範囲です。インデックスの選択性が高くなるほど、クエリの効率が高くなります。これは、選択性の高いインデックスを使用すると、MySQL が検索時により多くの行をフィルター処理できるためです。 一般的に、列プレフィックスの選択性はクエリのパフォーマンスを満たすのに十分高いですが、BLOB、TEXT、および VARCHAR 型の列の場合、MySQL ではこれらの列の全長のインデックス作成が許可されていないため、プレフィックス インデックスを使用する必要があります。この方法を使用するコツは、高い選択性を確保するのに十分な長さのプレフィックスを選択しながら、長すぎないようにすることです。 --データ テーブルを作成します。create table citydemo(city varchar(50) not null); citydemo(city) に挿入し、city から city を選択します。 -- 次の SQL ステートメントを 5 回繰り返します。 insert into citydemo(city) select city from citydemo; --city テーブルの名前を更新します。update citydemo set city=(select city from city order by rand() limit 1); --最も一般的な都市リストを見つけ、各値が45〜65回出現することを見つけます。 citydemo から count(*) を cnt,city として選択し、group by city で cnt desc limit 10 で並べ替えます。 -- 最も頻繁に出現する都市のプレフィックスを検索します。プレフィックスの 3 文字から始めて、以前よりも頻繁に出現していることを確認します。複数の文字をインターセプトして、都市が出現する回数を確認できます。select count(*) as cnt,left(city,3) as pref from citydemo group by pref order by cnt desc limit 10; citydemo から count(*) を cnt、left(city,7) を pref として選択し、group by pref、order by cnt desc limit 10 を実行します。 --この時点で、プレフィックスの選択性は完全な列の選択性に近いです--別の方法を使用して完全な列の選択性を計算することもできます。プレフィックス長が7に達すると、プレフィックス長を増やしても選択性の向上が非常に小さいことがわかります。select count(distinct left(city,3))/count(*) as sel3, count(distinct left(city,4))/count(*) as sel4、 count(distinct left(city,5))/count(*) as sel5、 count(distinct left(city,6))/count(*) as sel6、 count(distinct left(city,7))/count(*) as sel7、 count(distinct left(city,8))/count(*) as sel8 citydemo より; --計算が完了したら、プレフィックスインデックスを作成できます。alter table citydemo add key (city (7)); --注: プレフィックス インデックスは、インデックスを小さくして高速化するための効果的な方法ですが、欠点もあります。MySQL では、order by および group by にプレフィックス インデックスを使用できません。 インデックススキャンを使用してソートする
union all、in、またはインデックスを使用できますが、in が推奨されます。 範囲列ではインデックスを使用できます。範囲条件は <、> です。範囲列ではインデックスを使用できますが、範囲列に続く列ではインデックスを使用できません。インデックスは最大 1 つの範囲列に対して使用できます。 強制型変換はテーブル全体をスキャンします テーブルuser(id int,name varchar(10),phone varchar(11))を作成します。 テーブル user を変更し、インデックス idx_1(phone) を追加します。 select * from user where phone=13800001234; を説明します (インデックスはトリガーされません) select * from user where phone='13800001234'; (トリガーインデックス)を説明します。 頻繁に更新され、データの差別化が低いフィールドにインデックスを作成することはお勧めできません。
インデックスを作成する列では null 値が許可されないため、予期しない結果が発生する可能性があります。 テーブルを結合する必要がある場合、結合する必要があるフィールドは同じデータ型である必要があるため、3 つ以上のテーブルを使用しないことをお勧めします。 可能な限り制限を使用する 1 つのテーブル上のインデックスの数を 5 以下に制限することをお勧めします。 単一インデックスフィールドの数は 5 を超えることはできません (結合インデックス) インデックスを作成するときは、次の誤解を避ける必要があります。 > インデックスは多ければ多いほど良い(間違い) > 時期尚早な最適化、システムを理解せずに最適化する(エラー) 要約するこれで、MySQL インデックスの知識のヒントに関するこの記事は終了です。より関連性の高い MySQL インデックスの知識コンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: HTMLページでよく使われるいくつかの小さなメソッド
>>: Docker で FastDFS ファイル システムを構築する (マルチイメージ チュートリアル)
<br />「XXXのウェブサイトを見てみませんか?」といった質問をされることもあります...
結合クエリ結合クエリとは、2 つ以上のテーブル間のマッチング クエリを指し、一般的には水平操作と呼ば...
HTML では、一般的な URL はさまざまな方法で表現されます。相対 URL:コードをコピーコード...
ディスク クォータは、コンピューター内の指定されたディスクのストレージ制限です。つまり、管理者はユー...
目次ビジネスシナリオ:効果のデモンストレーション:ビジネスシナリオ: el-form を使用する場合...
CI を利用してリリース用の Docker イメージをビルドすることで、全員のバージョンリリース効率...
1. 基本的な文法コードをコピーコードは次のとおりです。埋め込み src=url注: 埋め込みはさま...
1. 公式5.0.3イメージを取得する [root@localhost ~]# docker pul...
コードをコピーコードは次のとおりです。 <span style="font-size...
コンテンツ属性は通常、::before および ::after 疑似要素で使用され、疑似要素のコンテ...
この記事では、クリックするとランダムグラフィックの生成を実現するJavaScriptの具体的なコード...
この記事の例では、ログインと登録の効果を実現するためのvueプロジェクトの具体的なコードを共有してい...
Web アプリケーションの開発とデバッグを行う際には、テストのためにブラウザのキャッシュをクリアした...
フォームの送信方法をまとめると次のようになります。 1. 送信ボタンを使用して送信します。送信ボタン...
エラーの説明Docker Desktop をインストールすると、WSL2 (Windows ベースの...