Mysql 高可用性および高性能ストレージ アプリケーション シリーズ 1 - インデックス

索引

索引付けの性質

  • これは、mysql の大学がデータを取得するのに役立つデータ構造です。
  • mysqlでは、データは最終的にハードディスクに保存されます

ディスクにアクセスすることは I/O 操作に相当します.Mysql にはページ (ページ) という概念があります. ページはツリー内のノードです. Mysql がページを取り出すたびに, つまりノードのデータ, そしてmysql はデフォルトでページを保存します. 16k データ.

二分木

二分木定義:

  • 左のサブツリーのすべての値がルート ノードより小さい
  • 右側のサブツリーのすべての値がルート ノードより大きい
  • 各ルート ノードは最大 2 つの子ノードに分割されます

平衡二分木の定義:

  • 比較的バランスが取れており、左右のサブツリー間の深さの差の絶対値は 1 を超えることはできません
  • 左右のサブツリーもバランスのとれた二分木でなければなりません
  • 二分木の極端なケースを回避できる

Bツリー構造

特徴:マルチフォーク(マルチレベル)

  • 1 つのノードは 2 つのチェックされた要素を格納でき、2 つ以上の子ノードを持つことができます
  • 二分木のいくつかの特性を持つ
  • バランスが取れており、各ノードのすべてのサブツリーは同じ高さで、比較的短い

要素数を計算します。

既知の条件: ノードのストレージ要素の数が x であると仮定すると、m 次 B ツリーには最大で m 個の子ノードがあります。

  • ルートノードの計算式:1 <= x < m-1
  • 非ルート ノード (切り上げ)、計算式:m/2 <= x <= m-1
  • 子ノードの数: y = x + 1、ルート ノードの計算式:2 <= y <= m
  • 非ルート ノード (切り上げ)、計算式:m/2 <= y <= m
  • 各ノードには最大 m 個の子ノードがあります
  • ルート ノードに加えて、各ノードには少なくともm/21 つの子ノードがあります。結果が割り切れない場合は切り上げられることに注意してください。
  • ルート ノードは空または一意であり、それ以外の場合は少なくとも 2 つの子ノードがあります
  • K 個の子ノードを持つノードには k 個のキーワードが必要です。つまり、m 個のデータを持つ m 個のフォークがあります。
  • 葉ノードの高さは一定です

1 つのノードに複数のデータを格納でき、1 つのページでより多くの有効なデータを取得できますが、同時にフォークが増えるため、データ レベルは確実に小さくなり、クエリの数は減少します。

3 層の Btree はいくつのデータを格納できますか? 1 つのデータが 1k の空間を占めると仮定すると (その識別はまず無視できます)、3 層の B-tree 構造に格納されるデータの数は次のようになります。

16 * 16 * 16 = 4096

テーブルに 500w のデータがある場合、階層は依然として非常に深いため、データのクエリを実行すると、多くのディスク I/O が発生します. (2) データは、ツリーのさまざまなレベルに順番に分散されます。小さいものから大きいものへ. 範囲検索を実行する場合, get 範囲が大きいほど, より多くのノードが取得されます. 極端な場合, すべてのデータが一度トラバースされます.これは, ツリー全体をトラバースすることと同じです. ノードが多いほど, I/O が多くなります.動作が発生し、パフォーマンスが動かなくなります。

B+ツリー

B+Tree は、B-Tree 構造の問題を解決します。

ここに画像の説明を挿入

  • リーフ ノードはデータ情報を保存し、非リーフ ノードは保存しません
  • ノードによって保存される要素ツリーは m に等しく、左が閉じて右が開いています
  • 葉ノードはポインタでリンクされています。これは範囲検索に便利です。葉ノードをトラバースするだけです

Mysql が B-Tree の代わりに B+Tree を使用するのはなぜですか? リーフ ノードはインデックスの並べ替えに基づいており、非リーフ ノードはデータを保存せず、より多くのインデックス データを保存し、1 回の I/O でより多くのターゲット データを取得します。最下位レベルのデータ構造は双方向リンク リストに属します。これは、並べ替えや範囲検索を行う場合に非常に便利であり、上記のノードをトラバースする必要はありません。

Mysqlの使い方

ミーサム

*.frm データテーブル定義情報
*.myi インデックス情報の保存
*.myd 保存データファイル

イノドブ

*.frm データテーブルの定義情報
*.ibd インデックス情報とデータ情報を保存

Innodb エンジンでは、テーブルが主キー インデックスを作成しない場合、データ テーブルは自動的に主キー インデックスを作成します。

返品フォーム

テーブルに戻るとは、その名前が示すように、テーブルに戻ることです。つまり、データが配置されている行を通常のインデックス (単一列のインデックスか結合インデックス、通常のインデックスと呼ばれます) に含まれていない行の主キー ID データからインデックスを取得します。したがって、テーブル リターンの生成にも一定の条件が必要です. 1 回のインデックス クエリですべての選択レコードを取得できる場合は、テーブルを返す必要はありません. 、テーブル リターン アクションが発生します。つまり、非主キー インデックスに基づくクエリでは、追加のインデックス ツリーをスキャンする必要があります。

Mysql の戻りテーブルは、InnoDB ストレージ エンジンの下でセカンダリ インデックスによってクエリされたインデックス列を指します. すべての列のデータを検索する必要がある場合は、データを取得するために主キー インデックスに移動する必要があります. このプロセスはテーブルに戻ると呼ばれます。

Id、Name、Age などのフィールドがあります。Id と Name はインデックスです。select Id,Name from Tableインデックス アイテムで使用されている場合は、直接返されます。select * from Table他のフィールドのクエリに使用されている場合は、主キー インデックスを使用する必要があります。データを取得するため、冗長なテーブル リターン操作が発生します。

カバリング インデックス:クエリを実行した列の複合インデックスを作成して、テーブルに戻らないようにすることを検討できます。

インデックスの左端一致の原則

名前、年齢、住所のインデックスが作成されると、B+Tree 構造はインデックスの順序に従って厳密に実行されます。

//使用到索引了
Select * from user where name = ? AND age = ? AND address = ? 

//使用到索引了
Select * from user where name = ?

//使用到了索引但是只用到name的索引了
Select * from user where name = ? AND address = ? 

質問

  • mysql が二分探索木または平衡二分木を使用しないのはなぜですか?
  • mysql が B-Tree の代わりに B+tree を使用するのはなぜですか?
  • Mysql が uuid を主キーとして使用することを推奨しないのはなぜですか?
  • mysql のクラスタ化インデックスとスパース インデックスを理解する方法は?
  • 「aaa%」のように、間違いなくインデックスを使用しますか?
  • クエリを作成することが推奨されないのはなぜですかselect * from?
  • 左端一致の原則を理解する方法は?
  • 主キー ID をインクリメントすることが提案されているのはなぜですか? B+Tree との関係は何ですか?
  • innodb エンジンが主キー インデックスの確立を必要とするのはなぜですか?

1. mysql が二分探索木と平衡二分木を使用しないのはなぜですか?
二分探索木はリンクされたリストと同等です. 極端な場合, データの最後の部分を照会するとテーブル全体が走査されます. mysql の各ノードの操作はディスク上の I/O 操作です. バランスの取れた二分木は回避しますが極端な場合、ノードのみ 1 つの要素を保存できます。これにより、各ノードが保存するデータが少なくなり、I/O 操作が増加し、パフォーマンスに影響します。

2. なぜ mysql は B-Tree の代わりに B+tree を使用するのですか?
1) リーフ ノードはポインタに関連付けられています. ソートおよび範囲検索の場合、効率が高くなります. すべてのノードをクエリするわけではないため、インデックス ベースのテーブル スキャンはより良くなり、インデックスベースのソートがより良くなります。
2) 子ノードにはデータ情報が保存されず、識別情報とポインタ情報のみが保存されるため、同じページ構造により多くのデータが保存され、ディスク I/O が削減されます。

3. mysql が B-Tree の使用を選択しないのはなぜですか?
計算によると、3 層の B-Tree ツリーに保存されているデータはまだ非常に小さく、データは異なるレベルの数に分散されています。範囲検索を行う場合、取得範囲が広いほど多くのノードが取得されます。
極端な場合、ツリー全体をたどることに相当し、ノード数が多いほどフェッチ回数が多くなり、I/O 操作が多くなるため、パフォーマンスがボトルネックになります。

4. mysql が主キーとして uuid を使用することを推奨しないのはなぜですか?
5. 主キー ID をインクリメントすることを提案するのはなぜですか? B+Tree との関係は何ですか?

  1. B+Tree は小さなものから大きなものへと順番にインデックスを作成し、隣接するノードを同じページに配置して、ページを最大限に活用し、フォークを減らす (つまり、検索の数を減らす) ためです。
  2. UUid には規則がないため、ページが無駄になります. Btree は、ストレージ構造が不合理であるため、UUid を主キーとして使用しません。

6. select * from Table ステートメントを使用してデータをクエリすることが推奨されないのはなぜですか?

Id、Name、Age などのフィールドがあります。Id と Name はインデックスです。select Id,Name from Tableインデックス アイテムで使用されている場合は、直接返されます。select * from Table他のフィールドのクエリに使用されている場合は、主キー インデックスを使用する必要があります。データを取得するため、冗長なテーブル リターン操作が発生します。

7. Innodb エンジンがプライマリ キー インデックスの確立を必要とするのはなぜですか?

これは Innodb の特殊なエンジン構造によって決定され、Innodb エンジンのデータはプライマリ キー ID の下に格納されます。

8. インデックス左端一致の原則

名前、年齢、住所のインデックスが作成されると、B+Tree 構造はインデックスの順序に従って厳密に実行されます。

//使用到索引了
Select * from user where name = ? AND age = ? AND address = ? 

//使用到索引了
Select * from user where name = ?

//使用到了索引但是只用到name的索引了
Select * from user where name = ? AND address = ? 

おすすめ

転載: blog.csdn.net/xuezhiwu001/article/details/129678652