BRINは「ブロックレンジインデックス」(Block Range Index)の略です。 BRINは、ある列がテーブル内の物理的な位置と自然な相関があるような、非常に大規模なテーブルのために設計されています。
BRINはブロックレンジ(block range)(または「ページレンジ(page range)」)として動作します。 ブロックレンジ(block range)は、テーブル内で物理的に隣接するページのグループです。それぞれのブロックレンジに対して、ある種の要約情報がインデックス内に格納されます。 たとえば、店舗の受注情報を格納するテーブルは、各々の受注時期を格納する日付列を持つでしょう。大抵の場合、より前の受注エントリは、テーブルのより前の方にあるでしょう。 郵便番号を管理するテーブルでは、ある市に属する郵便番号が自然にグループ化されることになるでしょう。
BRINインデックスは、通常のビットマップインデックススキャンを通じて要求されるクエリに使用することができます。 すなわち、インデックス内のレンジ要約情報が検索条件と一致すれば、BRINインデックスは、レンジ内の全タプルを返します。 クエリエクゼキュータの役割は、検索条件を再チェックし、条件に合致しないタプルを捨てることです。 つまり言い換えると、BRINインデックスには損失性があります。 BRINインデックスは非常に小さいため、それに対するスキャンは順スキャンに比べると小さなオーバヘッドしか与えません。しかし、あらかじめ条件に合致しないと分かっているテーブルの多くの部分をスキャンすることを避けることができます。
BRINインデックスに格納される特定のデータと、そのインデックスが対応できる特定のクエリは、インデックスに対応する各々の列に与えられた演算子クラスに依存します。 線形のソート順を持つデータ型は、ブロックレンジ内の最小値と最大値と格納する演算子クラスを持つことができます。 たとえば、幾何データ型は、ブロックレンジ内のすべてのオブジェクトを含む外接矩形を持つことでしょう。
ブロックレンジの大きさは、ストレージパラメータpages_per_range
でインデックス作成時に決定されます。
インデックスエントリの数は、リレーションのページ数をpages_per_range
に設定した数で割ったものと等しくなります。
ですから、pages_per_range
の設定値が小さいほど、インデックスは大きくなります(より多くのインデックスエントリを格納する必要があるので)が、反面、格納されたサマリーデータはより精密になり、インデックススキャンの際により多くのデータブロックをスキップすることができるようになります。
インデックスを作成した当初は、すべてのヒープページがスキャンされ、終端が不完全なものも含め、各々のレンジに対してサマリーインデックスタプルが作成されます。 新しいページにデータが登録されると、新しいタプルのデータを元に、すでにサマリー済みのページレンジのサマリー情報が更新されます。 最終サマリーレンジに適合しない新しいページが作成されると、そのレンジに対して自動的にはサマリータプルが作成されません。 これらのタプルは、後でサマリー処理が走って初期サマリー情報が作成されるまではサマリーされません。
ページレンジの初期サマリー処理を起動する複数の方法があります。 手動あるいはautovacuumのどちらでも良いですが、テーブルがバキュームされるとすべてのまだサマライズされていないページレンジがサマライズされます。 また、インデックスのautosummarizeパラメータが有効なら、これはデフォルトでは有効ではありませんが、そのデータベースに対してバキュームが実行されると、自動バキュームによってそのテーブル自体が処理されるかどうかにかかわらず、すべての挿入された未サマリーページレンジに対してサマリー処理が実行されます。 以下を見てください。
最後に、次の関数が利用できます。
すべての未サマリーレンジをサマライズするbrin_summarize_new_values(regclass)
|
もしまだサマライズされていなければ、指定されたページを含む指定されたレンジのみをサマライズするbrin_summarize_range(regclass, bigint)
|
自動サマリー機能が有効な場合、次のブロックレンジの最初のページの最初の項目の挿入が検出されると、同じデータベースで実行中の自動バキュームワーカーの次の実行の終了時に処理されるブロックレンジをターゲットとするサマリー機能を実行する要求がautovacuum
に送信されます。
もしリクエストキューが満杯ならばそのリクエストは記録されず、次のメッセージがサーバのログに送信されます。
LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was not recorded
この状態が発生すると、テーブルの次の通常バキュームが実行されるか、上で述べた関数のどれかが実行されるまでは、そのレンジはサマライズされない状態にとどまります。
反対に、レンジはbrin_desummarize_range(regclass, bigint)
関数で非サマリー化できます。
これは、既存の値が変更されたためにインデックスタプルがもはや値の表現としては適当でなくなった場合に有効です。
詳細は9.27.8を見てください。