选择 打开 改范围 完整检索页
受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10
当前 PostgreSQL 版本不在支持生命周期内。
您可以参阅当前版本的对应页面,或其他在上面列出的活跃大版本。

Chapter 65. BRIN 索引

65.1. 简介 #

BRIN 是块范围索引(Block Range Index)的缩写。 BRIN 旨在处理非常大的表,其中某些列与它们在表中的物理位置之间存在某种天然的相关性。 块范围是表中物理上相邻的一组页;索引会为每个块范围存储一些摘要信息。 例如,一个存储商店销售订单的表可能有一个日期列,表示每个订单的下单日期,而大多数情况下较早订单的条目也会较早出现在表中; 一个存储邮政编码列的表,则可能会自然地把同一城市的所有邮政编码分组在一起。

如果索引中存储的摘要信息与查询条件相一致BRIN 索引就可以通过常规位图索引扫描来满足查询,并返回每个范围内所有页上的全部元组。 查询执行器负责重新检查这些元组,并丢弃不匹配查询条件的元组 — 换句话说,这些索引是有损的。 由于 BRIN 索引非常小,与顺序扫描相比,扫描索引只会带来很小的额外开销, 但可以避免扫描那些已知不包含匹配元组的大块表数据。

BRIN 索引所存储的具体数据,以及它能够满足的具体查询, 取决于为该索引各列选择的操作符类。 例如,具有线性排序顺序的数据类型可以使用在每个块范围内存储最小值和最大值的操作符类; 几何类型则可能存储该块范围内所有对象的边界框。

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

65.1.1. 索引维护 #

在创建索引时,会扫描所有现有堆页,并为每个范围创建一个摘要索引元组,末尾那个可能不完整的范围也包括在内。 随着新页被数据填满,已经完成摘要的页范围会利用新元组中的数据更新其摘要信息。 当创建了一个不属于最后一个已摘要范围的新页时,该范围不会自动获得摘要元组; 这些元组会一直保持未摘要状态,直到稍后调用摘要操作,创建初始摘要。 可以使用brin_summarize_range(regclass, bigint)brin_summarize_new_values(regclass)函数手动调用这一过程;也可以在VACUUM处理该表时自动调用;或者在发生插入时,由 autovacuum 执行自动摘要。(最后一种触发方式默认禁用,可以通过autosummarize参数启用。)反之,可以使用brin_desummarize_range(regclass, bigint)函数对某个范围取消摘要;当现有值已经发生变化,以致索引元组不再是良好表示时,这会很有用。

当启用自动摘要时,每当一个页范围被填满,就会向 autovacuum 发送请求,要求对该范围执行定向摘要。该请求会在同一数据库中的某个自动清理工作进程下一次结束运行时得到处理。如果请求队列已满,该请求就不会被记录,并会向服务器日志发送一条消息:

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

发生这种情况时,该范围会在对该表执行下一次常规清理时正常完成摘要。