ブロック範囲インデックス( BRIN)は、データベースのインデックス作成技術です。非常に大きな[i]テーブルのパフォーマンスを向上させることを目的としています。
BRINインデックスは水平分割やシャーディングと同様の利点を提供しますが、パーティションを明示的に宣言する必要はありません。[1]
BRINは、大規模で、インデックスキー値がMinMax関数で簡単にソートおよび評価できるテーブル上のインデックスに適用できます。[ii]
BRINはもともと2013年に2ndQuadrantのAlvaro Herrera氏によって「Minmaxインデックス」として提案されました。[2]これまでの実装は、データベーステーブルの内部実装とストレージ技術に密接に結びついています。これにより効率的になりますが、特定のベンダーに限定されます。これまでのところ、PostgreSQLはPostgreSQL 9.5でこの特定の機能を備えたライブ製品を発表した唯一のベンダーです。[3] [4]他のベンダーも同様の機能について説明しており、[ 2] Oracle、[5] [6] Netezza「ゾーンマップ」、[7] Infobright「データパック」、[8] MonetDB [9] ORC/Parquetを使用したApache Hiveなどが含まれます。[10]
デザイン


BRIN は、大きなデータ ブロックをコンパクトな形式に「要約」することで動作します。これにより、データベース クエリからそれらの多くを除外するためのテストを効率的に実行できます。これらのテストでは、比較ごとに大きなデータ ブロックを除外します。大きなブロックを小さなタプルとして表し、多くのブロックを削除することで、BRIN は、データベース ノードが行ごとに調べる必要がある詳細データの量を大幅に削減します。[11]
大規模データベースのデータストレージは階層化され、チャンク化されており、テーブルストレージは「ブロック」に整理されています。各ブロックには、おそらく各チャンクに1MBが含まれています[iii] [13]。それらは、ディスクベースのストレージレイヤーから特定のブロックを要求することによって取得されます。BRINは、この上にある軽量のインメモリサマリーレイヤーです。インデックス内の各タプルは、1つのブロックに含まれるデータの範囲(最小値と最大値、およびブロックに対象の列の非NULLデータが含まれているかどうか)を要約します。[14]
関心のある値を含むテーブルの領域を特定する従来のインデックスとは異なり、BRINは「ネガティブインデックス」として機能し、 [5]明らかに関心のないブロックを示し、それ以上処理する必要はありません。
いくつかの簡単なベンチマークでは、インデックススキャンを使用すると、インデックスのないテーブルと比較して検索パフォーマンスが5倍向上することが示されています。[3] Bツリーと比較すると、メンテナンスのオーバーヘッドが回避されます。[2]
BRIN は非常に軽量であるため、メモリ内に完全に保持され、スキャン中のディスク オーバーヘッドを回避できます。B ツリーでは同じことが当てはまらない場合があります。B ツリーでは、テーブル内の約N 行ごとにツリー ノードが必要です(N は 1 つのノードの容量)。そのため、インデックスのサイズが大きくなります。BRIN では、ブロック (多数の行) ごとにタプルのみが必要なので、インデックスはディスクとメモリの違いを生むほど小さくなります。「狭い」テーブル[iv]の場合、B ツリー インデックスのボリュームはテーブル自体のボリュームに近づきます。BRIN は、その 5 ~ 15% に過ぎない場合があります。[15]
利点
検索とインデックススキャン
大規模なデータベース インデックスでは、通常、 B ツリーアルゴリズムが使用されます。BRIN は、常に B ツリーの代替となるわけではありませんが、インデックスのシーケンシャル スキャンを改良したものであり、インデックスが順序付けされ、検索対象がこれらの値の狭いセットであるという特定の条件を満たす場合に、特に (潜在的に大きな) 利点があります。一般的なケースでは、ランダム データの場合、B ツリーの方が優れている可能性があります。[3]
Oracle Exadata の Smart Scanning [6]と共有される BRIN 技術の特別な利点は、このタイプのインデックスをビッグ データまたはデータ ウェアハウスアプリケーションで使用することです。これらのアプリケーションでは、テーブルのほぼすべてが対象範囲とは無関係であることが分かっています。BRIN を使用すると、対象データが含まれている可能性のあるブロックのみを取得し、明らかに範囲外にあるブロックやこの列にデータが含まれていないブロックを除外することで、このような場合にテーブルを照会できます。
入れる
大きなテーブルを処理する際によくある問題は、検索にはインデックスの使用が必要ですが、このインデックスを維持すると新しいレコードの追加が遅くなることです。典型的な方法は、追加をグループ化して単一の一括トランザクションとして追加するか、インデックスを削除して新しいレコードのバッチを追加してからインデックスを再作成することです。これらは両方とも同時読み取り/書き込み操作を中断させるため、継続的に運営されているビジネスでは不可能な場合があります。[16]
BRINでは、インデックスの維持による速度低下はBツリーに比べて大幅に軽減されます。[17] Wongは、Bツリーではインデックスのない10GBのテーブルへの追加が85%遅くなったが、同等のBRINではオーバーヘッドは11%しかなかったと報告しています。[1]
インデックス作成
BRINは、Bツリーでは水平分割が必要となるような非常に大きなデータに対して作成される場合がある。[14]
BRINの作成もBツリーに比べて80%も高速です。[1]これは、コードを変更することなく、ドロップ・追加・再インデックスのアプローチを使用する既存のデータベースアプリケーションをリファクタリングするための有用な改善となります。
実装
テーブルの順序への依存
1 つのテーブル上の異なる列に複数の BRIN を定義できます。ただし、制限があります。
BRINは、キー値の順序がストレージ層のブロックの構成に従っている場合にのみ効率的です。[13] [15]最も単純なケースでは、キーの順序と一致するように、テーブルの物理的な順序(多くの場合、テーブル内の行の作成順序)が必要になる場合があります。このキーが作成日である場合、これは些細な要件である可能性があります。[14] : 9
データが本当にランダムである場合、または「ホット」データベース内のキー値の変化が大きい場合、BRIN の基礎となる仮定が崩れる可能性があります。すべてのブロックには「関心のある」エントリが含まれているため、BRIN 範囲フィルターによって早期に除外されるエントリはほとんどありません。
ほとんどの場合、BRIN はテーブルごとに 1 つのインデックスに制限されます。複数の BRIN を定義できますが、適切な順序付けが可能なのは 1 つだけです。2 つ (またはそれ以上) のインデックスの順序付け動作が類似している場合は、同じテーブルに複数の BRIN を定義することが可能であり、便利です。わかりやすい例としては、作成日と record_id 列の両方がレコード作成シーケンスとともに単調に増加する場合が挙げられます。その他の場合、キー値が単調ではない可能性がありますが、レコードの物理的な順序内に強力なグループ化がまだ存在する場合は、BRIN が効果的です。
Exadata ストレージ インデックス
BRIN は、Oracle Exadataの「ストレージ インデックス」といくつかの類似点があります。[2] [5] [18] Exadata は、アーキテクチャ スタックに「ストレージ レイヤー」という強力な概念を持っています。テーブル データは、ストレージ サーバー上のブロックまたは「ストレージ セル」に保持されます。これらのストレージ セルはストレージ サーバーに対して不透明であり、要求に応じて識別子によってデータベース エンジンに返されます。以前は、データベース ノードは、ストレージ セルをスキャンするためにすべてのストレージ セルを要求する必要がありました。[6]
ストレージインデックスは、このレイヤーでデータのプルーニングを提供し、もはや重要ではないセクションを効率的に示します。[13] [v] [19]ストレージインデックスはストレージサーバーのメモリにロードされるため、セルの要求が発行されると、検索値で述語化される可能性があります。これらはストレージインデックスと比較され、関連するセルのみがデータベースノードに返されます。
ストレージインデックスによるパフォーマンス上の利点は、インデックスされた列に多くのNULLが含まれている場合に最も顕著になります。スパースデータをスキャンする場合、パフォーマンス上の大きな利点が得られます。[20]
発達
PostgreSQLの開発は、AXLEプロジェクト(超大規模欧州データベース向け高度分析)の一環として実施されました。 [21]この作業は、欧州連合の第7次フレームワークプログラム(FP7/2007-2013)によって部分的に資金提供されました。[22]
PostgreSQL
PostgreSQLへの実装は2013年に初めて明らかになりました。[2] BRINは2016年の初めにPostgreSQLのリリース9.5で登場しました。[15] [23]
参照
注記
- ^ ここでの「大きい」とは、フィールドのサイズや全体のサイズではなく、テーブル内の行数を指します。
- ^ 多数のデータ項目を効率的に評価し、その最小値と最大値を返す関数。「最小値」と「最大値」の概念は広範囲に及び、並べ替え可能な任意のデータ型、またはその組み合わせに適用できます。
- ^ PostgreSQLのデフォルトのBRINチャンクサイズは128×8kページ、つまり1MBです。[3] Oracleはこれを「ストレージ領域」と呼び、デフォルトのサイズを1MBとしています。[12]
- ^ 表の列の幅は、インデックス列の幅よりわずかに広くなります。
- ^ Foote [13]は、インデックスは「Null が存在するかどうかを示すフラグ」を保持すると説明しています。これはおそらくタイプミスです。Oracle は、これを「負のインデックス」と表現し、「値が確実に含まれない領域を識別する」と説明しています[5]。このような場合、フラグは「 Nullのみが存在する」か「 Null以外の値が存在する」かを示すものとしてより明確に説明されます。
参考文献
- ^ abc Mark Wong (2014 年 10 月 10 日)。「テーブルのロードと B ツリーおよびブロック範囲インデックスの作成」。AXLE プロジェクト。
- ^ abcde Alvaro Herrera (2013-06-14). 「Minmax インデックス」. Pg Hackers .
- ^ abcd 「PostgreSQL 9.5 の新機能」。PostgreSQL。
- ^ 「第62章 BRINインデックス」。PostgreSQL 9.5.0ドキュメント。2016年。
- ^ abcd Arup Nanda (2011 年 5 月~6 月)。「スマート スキャンとストレージ インデックスの融合」。Oracle Magazine。Oracle。
- ^ abc 「Oracle Exadataのストレージ索引について」2015年6月2日。
- ^ 「Netezza では、圧縮、ゾーン マップ、結合の品質を高めるために、常に整数結合キーを使用します」。Netezza。2010 年。
- ^ 「データパック」。Infobright。2009年6月27日時点のオリジナルよりアーカイブ。
- ^ 「協調スキャン: DBMS における動的帯域幅共有」 2007 年、 723 ~ 734ページ。CiteSeerX 10.1.1.108.2662。
- ^ 「インデックス、ブルームフィルター、統計による Hive の最適化」 Jörn Franke. 2015 年。2016 年 3 月 4 日時点のオリジナルよりアーカイブ。2016年 5 月 24 日閲覧。
- ^ Herrera, Alvaro (2014 年 11 月 7 日). 「commitdiff - BRIN: Block Range Indexes」. git.postgresql.org . 2017 年 10 月 3 日閲覧。
- ^ 「Exadata のストレージ インデックスはいつ使用されますか?」OakTable.net。
- ^ abcd Richard Foote (2012 年 10 月 4 日)。「Exadata ストレージ インデックス - パート I」。
- ^ abc Mark Wong (2015年3月10日). 「PostgreSQLパフォーマンスプレゼンテーション」(PDF) . pp. 7– 10.
- ^ abc 「PostgreSQL 9.5 のブロック範囲 (BRIN) インデックス」。Python Sweetness。2015年 5 月 22 日。
- ^ Petr Jelinek (2014年11月28日). 「オンラインアップグレードの進捗状況」. AXLEプロジェクト.
- ^ Mark Wong (2014 年 10 月 10 日)。「増大するテーブルでのインデックス オーバーヘッド」。2Ndquadrant | Postgresql。
- ^ 「Oracle Sun Database Machine アプリケーション データ ウェアハウスのベスト プラクティス」。Oracle。1094934.1。
{{cite web}}:欠落または空|url=(ヘルプ) - ^ Marc Fielding (2010 年 7 月 20 日)。「Exadata の最もよく知られた秘密: ストレージ インデックス」
- ^ Kerry Osborne (2010 年 8 月 10 日)。「Oracle Exadata – ストレージ インデックス」
- ^ 「AXLE プロジェクト (非常に大規模なヨーロッパのデータベース向けの高度な分析)」。2014 年。
- ^ 「欧州連合の第 7 次フレームワーク プログラム (FP7/2007-2013)、助成契約番号 318633」。
{{cite web}}:欠落または空|url=(ヘルプ) - ^ Alvaro Herrera (2014-11-07). 「BRIN: ブロック範囲インデックス」. PostgreSQL . 2016-01-14閲覧。
