rknfish

rknfish

i need more love
github

講義#08:ツリーインデックス

コースを参照する

ノートを参照する

スライドを参照する

カバー

[[目次]]


1. テーブルインデックス#

テーブルインデックスは、属性のコピーであり、主に高速化のために使用されます。

テーブルインデックスは、次の 2 つの要素を考慮しています。

  • メンテナンスのコスト
  • 高速化の効果

2. B + ツリー#

B + ツリーの属性

B + ツリーは、自己バランス型のデータ構造であり、検索、挿入などの操作の時間複雑度は通常 $O (\log {n})$ であり、このデータ構造は比較的大きなデータブロックに最適化されています。

B + ツリーは、次の特徴を持つM分探索木です:

  • 完全にバランスしています(すべての葉ノードのレベルが同じです)
  • ルートノード以外のノードは、M/2-1 <= #keys <= M-1のキーを持ちます
  • 各ノードは、**k個のキーを持つ場合、k+1** 個の非空の子ノードを持ちます。

B + ツリーの例

B + ツリーでは、葉ノードは最終的に必要なキーを格納する場所です。したがって、最終的な値を葉ノードに基づいて検索する場合、次の 2 つの方法があります。

  1. 値が格納されている場所にポインタを記録します。
  2. 直接葉ノードに格納します。

B - ツリーと B + ツリーの比較#

B - ツリーと B + ツリーの主な違いは、B - ツリーのキーが葉ノード以外にも存在することです。したがって、B - ツリーはストレージスペースの利用において、明らかに B + ツリーよりも優れています。

したがって、次のような問題が発生する可能性があります。

  1. B - ツリーでは、ノード間を行き来する必要がありますが、B + ツリーでは直接スキャンできます。
  2. B - ツリーでは、値をノードに格納する方法を使用すると、クエリが遅くなる可能性があります。

可視化#

https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html

挿入#

挿入するために葉ノードを見つけます。サイズに基づいて挿入します。

ノードに十分なスペースがある場合、挿入は停止します。十分なスペースがない場合は、次の 2 つの手順を実行します。

  1. ノードを中央値で 2 つのノードに分割します。
  2. 中央値を親ノードに上に押し上げます。親ノードが存在しない場合は、親ノードを作成します。その後、親ノードに同じ操作を実行します。

削除#

削除するために葉ノードを見つけます。

葉ノードがキーを削除した後、少なくとも半分の容量がある場合、削除は停止します。

葉ノードにキーがM/2-1個しかない場合、次の 2 つの戦略があります。

  • 隣接ノードから値を持ってくる試み
  • 試みが失敗した場合、2 つのノードを結合する試み

選択条件#

ツリー構造のクエリの利点と欠点を持っています。

重複キー#

重複するキーを処理するための 2 つの方法があります。

  1. すべてのキーの後にレコード ID を追加して、各キーが一意であることを保証します。
  2. オーバーフローノードを使用して、これらの重複情報を保存します。
    オーバーフローノード

クラスタ化インデックス#

テーブルは通常、プライマリキーに基づいてインデックスが作成されます。

ただし、一部のデータベースでは、クラスタ化インデックスを使用し、テーブルに非表示のプライマリキーを追加します。他のデータベースでは、このインデックスを使用できない場合があります。


3. B + ツリーの設計選択肢#

ノードサイズ#

通常、ストレージデバイスが遅いほど、使用するノードサイズが大きくなります。

  • HDD:~1MB
  • SSD:~10KB
  • インメモリ:~512B

マージの閾値#

一部の DBMS では、常に半分の容量のノードをマージしない場合があります。

なぜなら、マージ操作を遅延させると、再バランスのコストを減らすことができるからです。

いくつかの比較的小さいノードを維持し、定期的にツリーを再構築する方が良い場合があります。

可変長キー#

  1. ポインタを使用する方法で、B + ツリーに値へのポインタのみを格納します。
  2. 可変長のノードを使用します。
  3. すべての値を B + ツリーに固定サイズで格納します。
  4. マップ形式で格納します。

ノード内検索#

  1. 線形
    • ノードを線形にスキャンします。
    • SIMD テクノロジーを使用してスキャンするデータ量を増やすことができます。
  2. 二分
    二分探索を使用して検索します。
  3. 補間
    値に基づいて位置を知るための補間です。
    補間

4. 最適化#

接頭辞圧縮#

共通の接頭辞を抽出することで圧縮します。

接頭辞圧縮

重複排除#

インデックスが一意でない場合、すべての値を 1 つのキーに統合することができます。

重複排除

接尾辞切り捨て#

この方法では、区別可能な小さな接頭辞長をノードから選択し、検索を行います。

切り捨て 1

切り捨て 2

ポインタのスイズリング#

B + ツリー内のページ ID をバッファプールに固定し、重複したディスク読み取りを回避し、アクセスを高速化することができます。次に、ページ ID のポインタをメモリ内の実際の値に置き換えることで、バッファプールの変換をバイパスして直接アクセスできます。

一括挿入#

ツリーの再構築は、下から上に向かって行う場合が最も速い方法です。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。