gpt4 book ai didi

postgresql - Postgres 选择 BTREE 而不是 BRIN 索引

转载 作者:行者123 更新时间:2023-11-29 11:19:17 27 4
gpt4 key购买 nike

我正在运行 Postgres 9.5 并且正在使用 BRIN 索引。我有一个包含大约 1.5 亿行的事实表,我正试图让 PG 使用 BRIN 索引。我的查询是:

select sum(transaction_amt), 
sum (total_amt)
from fact_transaction
where transaction_date_key between 20170101 and 20170201

我在列 transaction_date_key 上创建了 BTREE 索引和 BRIN 索引(默认 pages_per_range 值为 128)(上述查询指的是 2017 年 1 月至 2 月)。我原以为 PG 会选择使用 BRIN 索引,但它与 BTREE 索引一起使用。这是解释计划:

https://explain.depesz.com/s/uPI

然后我删除了 BTREE 索引,对表进行了清理/分析,然后重新运行查询,它确实选择了 BRIN 索引,但是运行时间相当长:

https://explain.depesz.com/s/5VXi

事实上,当使用 BTREE 索引而不是 BRIN 索引时,我的测试都更快。我以为应该是相反的?

我更喜欢使用 BRIN 索引,因为它的尺寸较小,但我似乎无法让 PG 使用它。

注意:我加载了从 2017 年 1 月到 2017 年 6 月(通过 transaction_date_key 定义)的数据,因为我读到物理表排序在使用 BRIN 索引时会有所不同。

有谁知道为什么 PG 选择使用 BTREE 索引以及为什么 BRIN 在我的情况下这么慢?

最佳答案

看来 BRIN 索引扫描的选择性不是很强——它返回了 3000 万行,所有这些都必须重新检查,这是花费时间的地方。

这可能意味着 transaction_date_key 与表中行的物理位置没有很好的相关性。

A BRIN index works通过将表 block 的范围“集中在一起”(多少可以使用存储参数 pages_per_range 进行配置,其默认值为 128)。存储每个 block 的索引值的最大值和最小值。

所以你表中的很多 block 范围包含 2017010120170201 之间的 transaction_date_key,并且必须扫描所有这些 block 以计算查询结果。

我看到两种改善情况的选择:

  • 降低 pages_per_range 存储参数。这将使索引更大,但会减少“误报” block 的数量。

  • transaction_date_key 属性上对表进行聚类。正如您所发现的,这需要(至少暂时)列上的 B 树索引。

关于postgresql - Postgres 选择 BTREE 而不是 BRIN 索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42098803/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com