67.1. Introduction

BRIN 代表块范围索引。 BRIN 设计用于处理非常大的表,其中某些列与其在表中的物理位置具有某些自然相关性。 块范围是表中在物理上相邻的一组页面;对于每个块范围,索引都会存储一些摘要信息。例如,存储 Store 销售订单的表中可能有一个日期列,每个订单都放置在该列上,大多数时候,较早订单的条目也会在表格中更早出现。一个存储邮政编码列的表可能会将一个城市的所有代码自然地分组在一起。

BRIN 索引可以通过常规的位图索引扫描满足查询,如果索引存储的摘要信息与查询条件“一致”,则 BRIN 索引将返回每个范围内所有页面中的所有 Tuples。查询执行程序负责重新检查这些 Tuples,并丢弃不符合查询条件的 Tuples,换句话说,这些索引是有损的。由于 BRIN 索引非常小,因此与 Sequences 扫描相比,扫描索引几乎不会增加开销,但是可以避免扫描表的大部分不包含匹配 Tuples 的部分。

BRIN 索引将存储的特定数据,以及该索引将能够满足的特定查询,取决于为索引的每一列选择的运算符类。例如,具有线性排序 Sequences 的数据类型可以具有存储每个块范围内的最小值和最大值的运算符类。几何类型可以存储块范围内所有对象的边界框。

块范围的大小是在索引创建时由pages_per_range storage 参数确定的。索引条目的数量等于页面中关系的大小除以为pages_per_range选择的值。因此,数字越小,索引就越大(因为需要存储更多的索引条目),但是同时存储的摘要数据可以更精确,并且在索引扫描期间可以跳过更多的数据块。

67 .1.1. 索引维护

在创建时,将扫描所有现有的堆页面,并为每个范围(包括最后可能不完整的范围)创建一个摘要索引 Tuples。当新页面充满数据时,已经汇总的页面范围将导致汇总信息被来自新 Tuples 的数据更新。当创建的新页面不在上一个汇总范围内时,该范围不会自动获取汇总 Tuples;这些 Tuples 保持未摘要状态,直到稍后调用摘要运行以创建初始摘要。可以使用brin_summarize_range(regclass, bigint)brin_summarize_new_values(regclass)函数手动调用此过程。 VACUUM处理表格时自动;或通过自动真空执行自动汇总(发生插入)。 (最后一个触发器默认情况下处于禁用状态,可以使用autosummarize参数启用.)相反,可以使用brin_desummarize_range(regclass, bigint)函数对范围进行汇总,这在索引 Tuples 不再是非常好的表示形式时非常有用,因为现有值已经改变。

启用自动汇总后,每次页面范围被填充时,都会发送一个请求给 autovacuum,以对其执行针对该范围的目标汇总,该请求将在下一个在同一数据库上运行的工作程序结束时完成。如果请求队列已满,则不会记录该请求,并且会将消息发送到服务器日志:

LOG:  request for BRIN range summarization for index "brin_wi_idx" page 128 was not recorded

发生这种情况时,该范围将在表的下一次常规抽真空期间正常汇总。