PostgreSQL 11 preview - BRIN索引接口功能扩展(BLOOM FILTER、min max分段)

本文主要是介绍PostgreSQL 11 preview - BRIN索引接口功能扩展(BLOOM FILTER、min max分段),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

标签

PostgreSQL , brin索引 , bloom filter , min max 分段


背景

BRIN索引是PG的一种块索引接口,存储指定连续数据块内被索引字段的元数据。

https://www.postgresql.org/docs/devel/static/brin.html

目前BRIN存储的元数据包括被索引字段在每个指定连续数据块区间的MIN,MAX值。所以对于比较分散的数据实际上效果是很差的,对于数据分布比较有时序属性的(或者说线性相关性很好)的字段,效果特别赞。

《HTAP数据库 PostgreSQL 场景与性能测试之 24 - (OLTP) 物联网 - 时序数据并发写入(含时序索引BRIN)》

《PostgreSQL BRIN索引的pages_per_range选项优化与内核代码优化思考》

《万亿级电商广告 - brin黑科技带你(最低成本)玩转毫秒级圈人(视觉挖掘姊妹篇) - 阿里云RDS PostgreSQL, HybridDB for PostgreSQL最佳实践》

《PostGIS空间索引(GiST、BRIN、R-Tree)选择、优化 - 阿里云RDS PostgreSQL最佳实践》

《自动选择正确索引访问接口(btree,hash,gin,gist,sp-gist,brin,bitmap...)的方法》

《PostgreSQL 并行写入堆表,如何保证时序线性存储 - BRIN索引优化》

《PostgreSQL 10.0 preview 功能增强 - BRIN 索引更新smooth化》

《PostgreSQL 聚集存储 与 BRIN索引 - 高并发行为、轨迹类大吞吐数据查询场景解说》

《PostgreSQL 物联网黑科技 - 瘦身几百倍的索引(BRIN index)》

《PostgreSQL 9.5 new feature - lets BRIN be used with R-Tree-like indexing strategies For "inclusion" opclasses》

《PostgreSQL 9.5 new feature - BRIN (block range index) index》

目前BRIN存在的可以改进的点:

当数据分布与HEAP存储的 线性相关性很差时,效果不好。如何改进呢?

多段MIN,MAX可能是一个非常有效果的改进方法,举个例子,我们有一个非常大的小区,有很多栋房子,然后每一栋房子我们保存了年龄最小和年龄最大的住户,比如说真实的分布是每栋楼都包含少部分是1-35岁,1个80岁的。

现在要找一位40岁的住户,如果是BRIN索引,会把所有的楼栋都返回给你原因是每栋楼的范围都是1-80岁。

如果使用多段存储,那么应该是1-35, 80。这样的话使用BRIN索引找40岁的住户直接返回0条记录。

1、现在PostgreSQL 11马上要提交的PATCH,就包含了multi min max的优化

https://commitfest.postgresql.org/17/1348/

2、第二个改进是引入了BRIN的BLOOM FILTER,我们知道BLOOM FILTER用少量的BIT位表示某被索引值是否存在,存在则设定这些BIT为1,如果对应的BITS不全为1,则说明没有这条记录。但是为了节约空间,BIT存在冲撞,例如某个值的BITS可能被其他一个或多个值的BITS覆盖。

那么就会出现一种情况,索引告诉你包含某个值,并不一定真的包含。但是索引告诉你不包含某个值,那就肯定不包含。

pic

所以

select * from tbl where a=? and b=? and c=? or d=?  

bloom会告诉你一个较大的结果集,然后再回HEAP表,使用FILTER过滤不满足条件的记录。

https://en.wikipedia.org/wiki/Bloom_filter

https://www.postgresql.org/docs/devel/static/bloom.html

目前使用bloom插件可以创建BLOOM索引,而PostgreSQL 11,会把这个功能加入BRIN索引接口中。

min max 分段

这个是POC里面的例子,可以看到使用分段MIN MAX后,BRIN索引的过滤性好了很多。

PATCH连接

https://commitfest.postgresql.org/17/1348/

https://www.postgresql.org/message-id/flat/c1138ead-7668-f0e1-0638-c3be3237e812@2ndquadrant.com#c1138ead-7668-f0e1-0638-c3be3237e812@2ndquadrant.com

To illustrate the improvement, consider this table:

    create table a (val float8) with (fillfactor = 90);  insert into a select i::float from generate_series(1,10000000) s(i);  update a set val = 1 where random() < 0.01;  update a set val = 10000000 where random() < 0.01;  

Which means the column 'val' is almost perfectly correlated with the
position in the table (which would be great for BRIN minmax indexes),
but then 1% of the values is set to 1 and 10.000.000. That means pretty
much every range will be [1,10000000], which makes this BRIN index
mostly useless, as illustrated by these explain plans:

    create index on a using brin (val) with (pages_per_range = 16);  explain analyze select * from a where val = 100;  QUERY PLAN  --------------------------------------------------------------------  Bitmap Heap Scan on a  (cost=54.01..10691.02 rows=8 width=8)  (actual time=5.901..785.520 rows=1 loops=1)  Recheck Cond: (val = '100'::double precision)  Rows Removed by Index Recheck: 9999999  Heap Blocks: lossy=49020  ->  Bitmap Index Scan on a_val_idx  (cost=0.00..54.00 rows=3400 width=0)  (actual time=5.792..5.792 rows=490240 loops=1)  Index Cond: (val = '100'::double precision)  Planning time: 0.119 ms  Execution time: 785.583 ms  (8 rows)  explain analyze select * from a where val between 100 and 10000;  QUERY PLAN  ------------------------------------------------------------------  Bitmap Heap Scan on a  (cost=55.94..25132.00 rows=7728 width=8)  (actual time=5.939..858.125 rows=9695 loops=1)  Recheck Cond: ((val >= '100'::double precision) AND  (val <= '10000'::double precision))  Rows Removed by Index Recheck: 9990305  Heap Blocks: lossy=49020  ->  Bitmap Index Scan on a_val_idx  (cost=0.00..54.01 rows=10200 width=0)  (actual time=5.831..5.831 rows=490240 loops=1)  Index Cond: ((val >= '100'::double precision) AND  (val <= '10000'::double precision))  Planning time: 0.139 ms  Execution time: 871.132 ms  (8 rows)  

Obviously, the queries do scan the whole table and then eliminate most
of the rows in "Index Recheck". Decreasing pages_per_range does not
really make a measurable difference in this case - it eliminates maybe
10% of the rechecks, but most pages still have very wide minmax range.

With the patch, it looks about like this:

    create index on a using brin (val float8_minmax_multi_ops)  with (pages_per_range = 16);  explain analyze select * from a where val = 100;  QUERY PLAN  -------------------------------------------------------------------  Bitmap Heap Scan on a  (cost=830.01..11467.02 rows=8 width=8)  (actual time=7.772..8.533 rows=1 loops=1)  Recheck Cond: (val = '100'::double precision)  Rows Removed by Index Recheck: 3263  Heap Blocks: lossy=16  ->  Bitmap Index Scan on a_val_idx  (cost=0.00..830.00 rows=3400 width=0)  (actual time=7.729..7.729 rows=160 loops=1)  Index Cond: (val = '100'::double precision)  Planning time: 0.124 ms  Execution time: 8.580 ms  (8 rows)  explain analyze select * from a where val between 100 and 10000;  QUERY PLAN  ------------------------------------------------------------------  Bitmap Heap Scan on a  (cost=831.94..25908.00 rows=7728 width=8)  (actual time=9.318..23.715 rows=9695 loops=1)  Recheck Cond: ((val >= '100'::double precision) AND  (val <= '10000'::double precision))  Rows Removed by Index Recheck: 3361  Heap Blocks: lossy=64  ->  Bitmap Index Scan on a_val_idx  (cost=0.00..830.01 rows=10200 width=0)  (actual time=9.274..9.274 rows=640 loops=1)  Index Cond: ((val >= '100'::double precision) AND  (val <= '10000'::double precision))  Planning time: 0.138 ms  Execution time: 36.100 ms  (8 rows)  

bloom filter

https://www.postgresql.org/docs/devel/static/bloom.html

参考

https://commitfest.postgresql.org/17/1348/

https://www.postgresql.org/message-id/flat/c1138ead-7668-f0e1-0638-c3be3237e812@2ndquadrant.com#c1138ead-7668-f0e1-0638-c3be3237e812@2ndquadrant.com

这篇关于PostgreSQL 11 preview - BRIN索引接口功能扩展(BLOOM FILTER、min max分段)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/338457

相关文章

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

详解Java如何向http/https接口发出请求

《详解Java如何向http/https接口发出请求》这篇文章主要为大家详细介绍了Java如何实现向http/https接口发出请求,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用Java发送web请求所用到的包都在java.net下,在具体使用时可以用如下代码,你可以把它封装成一

Go语言实现将中文转化为拼音功能

《Go语言实现将中文转化为拼音功能》这篇文章主要为大家详细介绍了Go语言中如何实现将中文转化为拼音功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 有这么一个需求:新用户入职 创建一系列账号比较麻烦,打算通过接口传入姓名进行初始化。想把姓名转化成拼音。因为有些账号即需要中文也需要英

基于WinForm+Halcon实现图像缩放与交互功能

《基于WinForm+Halcon实现图像缩放与交互功能》本文主要讲述在WinForm中结合Halcon实现图像缩放、平移及实时显示灰度值等交互功能,包括初始化窗口的不同方式,以及通过特定事件添加相应... 目录前言初始化窗口添加图像缩放功能添加图像平移功能添加实时显示灰度值功能示例代码总结最后前言本文将

Java后端接口中提取请求头中的Cookie和Token的方法

《Java后端接口中提取请求头中的Cookie和Token的方法》在现代Web开发中,HTTP请求头(Header)是客户端与服务器之间传递信息的重要方式之一,本文将详细介绍如何在Java后端(以Sp... 目录引言1. 背景1.1 什么是 HTTP 请求头?1.2 为什么需要提取请求头?2. 使用 Spr

五大特性引领创新! 深度操作系统 deepin 25 Preview预览版发布

《五大特性引领创新!深度操作系统deepin25Preview预览版发布》今日,深度操作系统正式推出deepin25Preview版本,该版本集成了五大核心特性:磐石系统、全新DDE、Tr... 深度操作系统今日发布了 deepin 25 Preview,新版本囊括五大特性:磐石系统、全新 DDE、Tree

使用Python实现批量访问URL并解析XML响应功能

《使用Python实现批量访问URL并解析XML响应功能》在现代Web开发和数据抓取中,批量访问URL并解析响应内容是一个常见的需求,本文将详细介绍如何使用Python实现批量访问URL并解析XML响... 目录引言1. 背景与需求2. 工具方法实现2.1 单URL访问与解析代码实现代码说明2.2 示例调用

oracle数据库索引失效的问题及解决

《oracle数据库索引失效的问题及解决》本文总结了在Oracle数据库中索引失效的一些常见场景,包括使用isnull、isnotnull、!=、、、函数处理、like前置%查询以及范围索引和等值索引... 目录oracle数据库索引失效问题场景环境索引失效情况及验证结论一结论二结论三结论四结论五总结ora

最好用的WPF加载动画功能

《最好用的WPF加载动画功能》当开发应用程序时,提供良好的用户体验(UX)是至关重要的,加载动画作为一种有效的沟通工具,它不仅能告知用户系统正在工作,还能够通过视觉上的吸引力来增强整体用户体验,本文给... 目录前言需求分析高级用法综合案例总结最后前言当开发应用程序时,提供良好的用户体验(UX)是至关重要

python实现自动登录12306自动抢票功能

《python实现自动登录12306自动抢票功能》随着互联网技术的发展,越来越多的人选择通过网络平台购票,特别是在中国,12306作为官方火车票预订平台,承担了巨大的访问量,对于热门线路或者节假日出行... 目录一、遇到的问题?二、改进三、进阶–展望总结一、遇到的问题?1.url-正确的表头:就是首先ur