vvo*_*dra 6 postgresql index-tuning
我在 BRIN 索引的 OLAP 查询中发现了许多用例,因为它们要小得多,并且速度与 BTREE 索引处于同一数量级。
通常,我使用 BRIN 索引来单调(或接近)增加时间戳列。在我们的 OLTP 数据库中,它们紧密地放置在磁盘上,因为随着时间的推移,它们自然会按顺序写入。
在我们的仓储 Postgres 实例中,表的某些部分是大批量加载的,不一定按时间排序。
是否有一些分析查询可以告诉我数据是否放置得太随机而无法使用 BRIN,即使列值分布似乎应该遵循创建 BRIN 索引的所有先决条件?
BRIN 索引仅对大表(数千个数据页或更多)有意义。(您已经知道这一点,只是为了指导公众。)但是如何判断行是否进行了足够的物理排序呢?
手册给出了一个提示:
BRIN 索引(块范围索引的简写)存储有关存储在表的连续物理块范围中的值的摘要。因此,它们对于值与表行的物理顺序密切相关的列最有效 。
大胆强调我的。
ANALYZE
收集存储在 中的相应统计数据pg_statistic
。人类最好通过correlation
系统视图中的列进行访问:pg_stats
correlation
float4
物理行排序和列值的逻辑排序之间的统计相关性。范围从 -1 到 +1。当该值接近 -1 或 +1 时,由于减少了对磁盘的随机访问,因此该列上的索引扫描预计会比该值接近零时更便宜。(如果列数据类型没有运算符,则该列为空
<
。)
所有统计数据均基于行样本,因此即使是最新的,也只是估计值。ANALYZE
您可以通过增加样本量来提高有效性,即设置更高的“统计目标”——当然,这也会增加成本。默认default_statistics_target
值为 100,这对于大多数用途来说都可以,但对于具有非平凡数据分布(用于排序和过滤)的大表的列来说通常太低。看:
您甚至可以暂时增加统计目标,运行ANALYZE
并重置该值,以获得具有更高有效性的一次性相关性。
因此,一旦分析了表(手动或通过autovacuum
)检查:
SELECT schemaname, tablename, attname, n_distinct, correlation
FROM pg_stats
WHERE schemaname = 'public'
AND tablename = 'tbl'
AND attname = 'my_index_col';
Run Code Online (Sandbox Code Playgroud)
接近correlation
0意味着 BRIN 指数将毫无用处。
接近correlation
1 (或-1)意味着 BRIN 指数非常好。
n_distinct
(相对于总计数)或负比率接近 0,您可以pages_per_range
相应地增加设置(默认为 128)。n_distinct
(相对于总计数)或接近 -1 的负比率,您可以pages_per_range
相应地减少设置。介于两者之间的一切都是灰色地带。许多因素在起作用。还很大程度上取决于平均行大小和典型查询。根据我的经验,接近 0 或 1 / -1 的值很常见,这使得决策变得很容易。
也就是说,如果表排序不够,您可以使用阻塞性较小的社区工具pg_squeeze或pg_repack之一来进行排序。对于大表来说,按排序顺序重写整个表的成本很高,并且如果存在(或+ ) 操作,情况会随着时间的推移而恶化。但可以为某些用例付费。看:CLUSTER
UPDATE
DELETE
INSERT