62.1. はじめに

BRINは「ブロックレンジインデックス」(Block Range Index)の略です。 BRINは、ある列がテーブル内の物理的な位置と自然な関係があるような、非常に大規模なテーブルのために設計されています。 ブロックレンジ(block range)は、テーブル内で物理的に隣接するページのグループです。それぞれのブロックレンジに対して、ある種の要約情報がインデックス内に格納されます。 たとえば、店舗の受注情報を格納するテーブルは、各々の受注時期を格納する日付列を持つでしょう。大抵の場合、より前の受注エントリは、テーブルのより前の方にあるでしょう。 郵便番号を管理するテーブルでは、ある市に属する郵便番号が自然にグループ化されることになるでしょう。

BRINインデックスは、通常のビットマップインデックススキャンを通じて要求されるクエリに使用することができます。 すなわち、インデックス内のレンジ要約情報が検索条件と一致すれば、BRINインデックスは、レンジ内の全タプルを返します。 クエリエグゼキュータの役割は、検索条件を再チェックし、条件に合致しないタプルを捨てることです。 つまり言い換えると、BRINインデックスには損失性があります。 BRINインデックスは非常に小さいため、それに対するスキャンは順スキャンに比べると小さなオーバヘッドしか与えません。しかし、あらかじめ条件に合致しないと分かっているテーブルの多くの部分をスキャンすることを避けることができます。

BRINインデックスに格納される特定のデータと、そのインデックスが対応できる特定のクエリは、インデックスに対応する各々の列に与えられた演算子クラスに依存します。 線形のソート順を持つデータ型は、ブロックレンジ内の最小値と最大値と格納する演算子クラスを持つことができます。 たとえば、幾何データ型は、ブロックレンジ内のすべてのオブジェクトを含む外接矩形を持つことでしょう。

ブロックレンジの大きさは、ストレージパラメータpages_per_rangeでインデックス作成時に決定されます。 インデックスエントリの数は、リレーションのページ数をpages_per_rangeに設定した数で割ったものと等しくなります。 ですから、pages_per_rangeの設定値が小さいほど、インデックスは大きくなります(より多くのインデックスエントリを格納する必要があるので)が、反面、格納されたサマリデータはより精密になり、インデックススキャンの際により多くのデータブロックをスキップすることができるようになります。

62.1.1. インデックスの保守

インデックスを作成した当初は、すべてのインデックスページがスキャンされ、終端が不完全なものも含め、各々のレンジに対してサマリーインデックスタプルが作成されます。 新しいページにデータが登録されると、新しいタプルのデータを元に、すでにサマリ済みのページレンジのサマリー情報が更新されます。 最終サマリーレンジに適合しない新しいページが作成されると、そのレンジに対して自動的にはサマリタプルが作成されません。 これらのタプルは、後でサマリー処理が走って初期サマリー情報が作成されるまではサマリーされません。 この処理は、手動でbrin_summarize_new_values(regclass)関数を起動するか、VACUUMがそのテーブルを処理する際に自動的に行われます。