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


BRINは、大きなデータブロックをコンパクトな形式に「要約」することで動作し、データベースクエリから多くのデータを早期に効率的に除外するためのテストを実行できます。これらのテストでは、比較ごとに大きなデータブロックが除外されます。大きなブロックを小さなタプルとして表現し、多くのブロックを除外することによって、BRINは早い段階でデータ量を削減し、データベースノードが行ごとに検査する必要のある詳細データの量を大幅に削減します。[ 11 ]
大規模データベースのデータストレージは階層化され、チャンク化されており、テーブルストレージは「ブロック」に編成されています。各ブロックには、各チャンクに約 1MB のデータが含まれており[ iii ] [ 13 ]、ディスクベースのストレージ層から特定のブロックを要求することで取得されます。BRIN は、この上に構築された軽量のインメモリ要約層です。インデックス内の各タプルは、1 つのブロックに含まれるデータの範囲、つまり最小値と最大値、およびブロックに対象の列の非 null データが含まれているかどうかについて要約します。[ 14 ]
関心のある値を含むテーブルの領域を特定する従来のインデックスとは異なり、BRINは「ネガティブインデックス」として機能し[ 5 ] 、明らかに関心のないブロックを示し、したがってそれ以上処理する必要はありません。
いくつかの簡単なベンチマークでは、インデックススキャンを使用すると、インデックスのないテーブルと比較して検索パフォーマンスが5倍向上することが示唆されています。[ 3 ] Bツリーと比較すると、メンテナンスのオーバーヘッドを回避できます。[ 2 ]
BRINは非常に軽量であるため、完全にメモリ内に保持することができ、スキャン中のディスクオーバーヘッドを回避できます。Bツリーの場合はそうとは限りません。Bツリーでは、テーブルの約N行ごとにツリーノードが必要となり、Nは単一ノードの容量であるため、インデックスサイズが大きくなります。BRINは(多数の行からなる)ブロックごとにタプルのみを必要とするため、インデックスは十分に小さくなり、ディスクとメモリの差が生まれます。「狭い」テーブル[ iv ]の場合、 Bツリーインデックスのボリュームはテーブル自体のボリュームに近づきますが、BRINはわずか5~15%程度になる可能性があります。[ 15 ]
大規模なデータベースインデックスでは、通常、Bツリーアルゴリズムが使用されます。BRINは必ずしもBツリーの代替となるものではなく、インデックスのシーケンシャルスキャンを改善するものであり、インデックスが特定の条件を満たして順序付けられ、検索対象がこれらの値の狭いセットである場合に特に(そして潜在的に大きな)利点があります。一般的なケースでは、ランダムなデータの場合、Bツリーの方が優れている可能性があります。[ 3 ]
Oracle ExadataのSmart Scanning [ 6 ]と共通するBRIN技術の特に優れた点は、ビッグデータやデータウェアハウスアプリケーションでこのタイプのインデックスを使用できることです。これらのアプリケーションでは、テーブルのほぼすべてが関心のある範囲とは無関係であることがわかっています。BRINを使用すると、関心のあるデータが含まれている可能性のあるブロックのみを取得し、明らかに範囲外である、またはこの列のデータが含まれていないブロックを除外することで、このような場合にテーブルをクエリできます。
大規模テーブルの処理における一般的な問題は、検索にはインデックスの使用が必要であるが、このインデックスの維持によって新しいレコードの追加が遅くなることである。従来は、追加をまとめて単一の一括トランザクションとして追加するか、インデックスを削除し、新しいレコードのバッチを追加してからインデックスを再作成するという方法が取られてきた。これらの方法はいずれも同時読み取り/書き込み操作を妨げ、継続的に稼働するビジネスでは実行できない場合がある。[ 16 ]
BRIN では、インデックスの維持による速度低下は B-tree に比べて大幅に軽減されます。[ 17 ] Wong は、インデックスのない 10GB テーブルへの追加は B-tree で 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は有効です。
BRIN はOracle Exadata の「ストレージ インデックス」といくつかの類似点があります。[ 2 ] [ 5 ] [ 18 ] Exadata は、アーキテクチャ スタックに「ストレージ レイヤー」という強力な概念を持っています。テーブル データは、ストレージ サーバー上のブロックまたは「ストレージ セル」に保持されます。これらのストレージ セルはストレージ サーバーに対して不透明であり、識別子によって要求に応じてデータベース エンジンに返されます。以前は、データベース ノードは、ストレージ セルをスキャンするためにすべてのストレージ セルを要求する必要がありました。[ 6 ]
ストレージインデックスはこのレイヤーでデータ剪定を提供し、それ以上関心のないセクションを効率的に示します。[ 13 ] [ v ] [ 19 ]ストレージインデックスはストレージサーバーのメモリにロードされるため、セルの要求が発行されると、検索値で述語付けできます。これらはストレージインデックスと比較され、関連するセルのみがデータベースノードに返されます。
ストレージインデックスによるパフォーマンス上の利点は、インデックス付き列に多くのヌル値が含まれている場合に最も顕著になります。疎なデータをスキャンする場合、パフォーマンス上の大きな利点が得られます。[ 20 ]
PostgreSQL の開発は、 AXLE プロジェクト(Advanced Analytics for Extremely Large European Databases) [ 21 ]の一環として行われました。この作業は、欧州連合の第 7 次フレームワーク プログラム(FP7/2007-2013) から部分的に資金提供を受けました。[ 22 ]
PostgreSQL の実装は 2013 年に初めて明らかになった。[ 2 ] BRIN は2016 年初頭のPostgreSQLリリース 9.5 に登場した。[ 15 ] [ 23 ]
{{cite web}}:欠落または空欄|url=(ヘルプ){{cite web}}:欠落または空欄|url=(ヘルプ)