Postgresql 中文操作指南

71.1. Introduction #

BRIN 表示块范围索引。BRIN 旨在处理具有非常大的表的表,其中某些列与它们在表内的物理位置具有一定的自然相关性。

BRIN 在 block ranges (或“页面范围”)方面起作用。块范围是表中物理上相邻的一组页面;针对每个块范围,索引会存储一些摘要信息。例如,存储某个商店的销售订单的表可能有一个日期列,每个订单都会在此日期列上放置,并且大多数情况下,早期订单的条目也会早些显示在表中;存储邮政编码列的表可能将某一城市的邮政编码组合在一起。

BRIN 索引可以通过常规位图索引扫描来满足查询,并将返回每个范围内的所有页面中的所有元组(如果索引存储的摘要信息 consistent 满足查询条件)。查询执行器负责重新检查这些元组并丢弃不满足查询条件的元组——换句话说,这些索引是有损的。由于 BRIN 索引非常小,因此与顺序扫描相比,扫描索引几乎没有开销,但可以避免扫描已知不包含匹配元组的大部分表。

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

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

71.1.1. Index Maintenance #

在创建时,扫描所有现有的堆页面,并针对每个范围(包括末尾可能不完整的范围)创建一个摘要索引元组。当新页面填满数据时,已经过摘要的页面范围将导致摘要信息使用新元组的数据进行更新。在创建不属于上次总结的范围的新页面时,新页面所属的范围不会自动获取摘要元组;这些元组将保持未总结状态,直到以后调用总结运行,为该范围创建初始总结。

有几种方法可以触发页面范围的初始汇总。如果表是真空的,无论是手动还是通过 autovacuum,所有现有的未汇总页面范围都会汇总。此外,如果启用了索引的 autosummarize参数(默认情况下没有启用),那么无论表本身是否由自动真空处理,只要在该数据库中运行自动真空,就会汇总所有已填满的未汇总页面范围;请参见下文。

最后,可以使用以下功能:

当启用自动总结时,当检测到对下一个块范围的第一个页面的第一个项目进行插入时,请求将被发送到 autovacuum ,以便针对块范围执行定向总结,以在下一次自动清理工作器在同一数据库中完成运行时完成。如果请求队列已满,则不会记录请求,并且会向服务器日志发送一条消息:

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

发生这种情况时,该范围将保持未总结状态,直到在表上执行下一次定期清理运行,或调用上面提到的函数之一。

相反,可以使用 _brin_desummarize_range(regclass, bigint)_函数对范围进行取消汇总,这在索引元组不再是很好的表示由于现有值已更改时很有用。有关详细信息,请参见 Section 9.27.8