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

71.1. 简介

71.1.1. 索引维护

BRIN stands for Block Range Index. BRIN is designed for handling very large tables in which certain columns have some natural correlation with their physical location within the table.

BRIN works in terms of block ranges (or page ranges). A block range is a group of pages that are physically adjacent in the table; for each block range, some summary info is stored by the index. For example, a table storing a store's sale orders might have a date column on which each order was placed, and most of the time the entries for earlier orders will appear earlier in the table as well; a table storing a ZIP code column might have all codes for a city grouped together naturally.

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

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

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

71.1.1. 索引维护

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

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

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

brin_summarize_new_values(regclass) which summarizes all unsummarized ranges;
brin_summarize_range(regclass, bigint) which summarizes only the range containing the given page, if it is unsummarized.

当启用自动摘要时,会向autovacuum发送请求,以在检测到下一个块范围的第一页的第一项插入时执行有针对性的摘要, 在同一数据库中的下一个autovacuum工作完成后执行。如果请求队列已满,则不记录请求,并向服务器日志发送消息:

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

当发生这种情况时,范围将保持未摘要状态,直到表上的下一个常规vacuum运行,或者调用上述函数之一。

相反,可以使用brin_desummarize_range(regclass, bigint)函数对范围进行反汇总, 当索引元组不再是一个很好的表示,因为现有值已经改变时,这是很有用的。 有关详细信息,请参见第 9.27.8 节