9.3 9.4 9.5 9.6 10 11 12 13 14 Current(15)
阿里云PostgreSQL 问题报告 纠错本页面

71.1. 简介

71.1.1. 索引维护

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

BRINblock ranges (或 page ranges)为单位工作。 块范围是表中物理上相邻的一组页面;对于每个块范围,索引会存储一些摘要信息。 例如,一个存储商店销售订单的表可能有一个日期列,表示每个订单的下单日期,大多数情况下较早的订单条目也会在表格中较早出现; 一个存储邮政编码列的表可能会自然地将同一城市的所有邮政编码分组在一起。

如果索引中存储的摘要信息与查询条件一致BRIN 索引可以通过常规的位图索引扫描满足查询,并且将会返回每个范围中所有页面 中的所有元组。查询执行器负责再次检查这些元组并且抛弃掉那些不匹配查询条 件的元组 — 换句话说,这些索引是有损的。由于一个BRIN 索引很小,扫描这种索引虽然比使用顺序扫描多出了一点点开销,但是可能会避 免扫描表中很多已知不包含匹配元组的部分。

一个BRIN索引将存储的特定数据以及该索引将能 满足的特定查询,都依赖于为该索引的每一列所选择的操作符类。具有一种 线性排序顺序的数据类型的操作符类可以存储在每个块范围内的最小和最大 值,例如几何类型可能会存储在块范围内的所有对象的外包盒。

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

71.1.1. 索引维护

在创建时,所有现有的堆页面都会被扫描,并为每个范围创建一个摘要索引元组,包括可能不完整的范围在内。 随着新页面被填充数据,已经被总结的页面范围将导致摘要信息被更新,使用新元组的数据。 当创建一个新页面,不在最后总结的范围内时,新页面所属的范围不会自动获得一个摘要元组; 这些元组保持未总结状态,直到稍后调用总结运行,为该范围创建初始摘要。

有几种方法可以触发页面范围的初始摘要。如果表被手动或通过 autovacuum进行了清理,所有现有的未摘要的 页面范围都会被摘要。 另外,如果索引的 autosummarize参数被启用(默认情况下未启用), 那么每当数据库中运行自动清理(autovacuum)时,将对所有已填充的未摘要的页面范围进行摘要处理, 无论表本身是否由自动清理(autovacuum)处理;请参见下文。

最后,可以使用以下函数:

brin_summarize_new_values(regclass) 它总结了所有未总结的范围;
brin_summarize_range(regclass, bigint) 如果未汇总,则仅汇总包含给定页面的范围。

当启用自动摘要时,会向autovacuum发送请求,以在检测到下一个块范围的第一页的第一项插入时执行有针对性的摘要, 在同一数据库中的下一个自动清理(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 节