带你认识PostgreSQL检索神器——Brin Index

news/2024/7/9 22:09:45 标签: 数据库, 分布式, postgresql, 索引

了解更多Greenplum技术干货,欢迎访问Greenplum中文社区网站

引言

Greenplum是一款强大而稳定的企业级分布式数据库。虽然基于 PostgreSQL,但Greenplum针对大数据的场景和用户对性能的极致追求开发了大量的特性和做了极致甚至苛刻的优化。此外,Greenplum紧密拥抱Postgres社区,以敏捷的方式快速升级Postgres内核。在Postgres 9.5的内核中,Postgres引入了一种全新的索引类型,名为Brin Index,本文将详细介绍Brin Index的内部实现以及性能表现。

01 什么是Brin Index

Brin全称Block Range Indexes,顾名思义即数据块范围的索引,它的设计初衷是为了解决当数据表极其庞大时的迅速扫描问题。

众所周知,Heap表以页面为单位进行组织,所以表的扫描也是以页面为单位。Brin索引的基本思想就是在索引中记录一组连续页面中字段值的大致统计信息,例如连续页面里某字段的最大值和最小值,页面扫描的时候根据Brin统计信息和查询条件直接跳过明显不符合查询条件的页面,从而达到快速扫描的效果。

在实际的查询计划中,位图扫描基于Brin索引完成整个扫描过程,如下所示:

gpadmin=# explain select * from t1 where c1 > 10 and c1 < 100;
-----------QUERY PLAN--------------
Gather Motion 3:1  (slice1; segments: 3)  (cost=400.00..404.04 rows=1 width=64)
  ->  Bitmap Heap Scan on t1  (cost=400.00..404.02 rows=1 width=64)
     Recheck Cond: ((c1 > 10) AND (c1 < 100))
        ->  Bitmap Index Scan on t1_idx_1  (cost=0.00..400.00 rows=1 width=0)
            Index Cond: ((c1 > 10) AND (c1 < 100))

第一部分,Bitmap Index Scan使用Brin索引和查询条件构造位图,记录有效页面并过滤掉绝大多数无用的页面,第二部分,Bitmap Heap Scan基于位图精准扫描有效的页面并使用查询条件对页面内元组进行二次过滤。实际上,在Brin索引出现之前,位图扫描通常使用Btree索引来构造位图,关于位图扫描的详细介绍,读者可以参考我们的另外一篇文章Greenplum执行器位图——让查询更有效。

02 Heap表的Brin索引实现

了解Brin索引实现的关键在于认识Brin索引文件的布局,Brin索引文件同样以页为单位进行存储,其布局如下图所示:

从图中可以看到,Brin索引文件中的页面有多种类型,其中比较重要的是Revmap页和Regular页,Revmap页中存放这一个叫做页面范围映射的结构(简称revmap),其中的每一条记录都保存了 <页面范围ID, Regular Page Tuple ID>的映射关系。

一个页面范围单位由pages_per_range参数来决定,默认是128个连续页面为一个页面范围单位,用户在创建Brin索引的时候可以指定一个页面范围的大小,例如:

create index idx_t1_id on t1 using brin (id) with (pages_per_range=64);

Regular Page中存放Brin索引元组,不同于Btree索引,Brin索引元组中保存着一个页面范围单位对应的统计信息,例如Min/Max,显然通过Revmap结构就能得到一个页面范围及其对应的统计信息。

当一个页面范围内的Heap页面添加了新的tuple并且新的tuple的值打破了该页面范围原来的统计信息边界,我们需要更新相应的Brin索引元组。当一个tuple从一个Heap页面删除时,我们可以不更新其对应的Brin索引,这样会造成统计信息没有及时更新,但是正确性是没有问题的,在Vacuum的时候,Vaccum会重新统计各个页面范围的边界,让索引信息更加的准确。

当Bitmap Index Scan构建位图的时候,我们对revmap进行顺序扫描,如果查询条件满足一个页面范围的统计边界条件,那么该页面范围内的所有页面都会用于构建位图,否则的话该页面范围内的所有页面将会被跳过。

03 Brin索引的性能表现

该部分我们对比一下Brin索引和Btree索引

首先创建一张表并插入数据

create table t1 (c1 int, c2 text, c3 text);
insert into t1 select i, 'ssfesregeugruehpeoghregygeye', 'frheuogygryeosihfuiewhurheuhre' from generate_series(1, 10000000) i;
gpadmin=# \d+
              List of relations
Schema | Name | Type  |  Owner  | Storage |  Size  | Description
--------+------+-------+---------+---------+--------+-------------
 public | t1   | table | gpadmin | heap    | 881 MB |
(1 row)

可以看到t1表的大小大约在900MB左右。

同时在t1上创建Brin索引和Btree索引

create index t1_idx_1 on t1 using brin(c1);
create index t1_idx_2 on t1 using btree(c1);
gpadmin=# \di+
List of relations
Schema | Name | Type | Owner | Table | Size | Description
--------+----------+-------+---------+-------+--------+-------------
public | t1_idx_1 | index | gpadmin | t1  | 768 kB |
public | t1_idx_2 | index | gpadmin | t1  | 213 MB |

可以看到,Brin索引的大小仅为768KB,而Btree索引的大小为213MB,显然在索引大小上,Brin索引有较大的优势,这也是Brin索引最大的一个特点,尤其当数据表及其大的时候,Brin索引的大小优势会显得极其吸引人。

同时,Brin索引在查询性能方面也有不错的提升。

当不使用索引的情况下,下面查询耗时4080ms。

gpadmin=# select count(*) from t1 where c1 > 10 and c1 < 1000;
count
-------
 989
 (1 row)
 
 Time: 4080.735 ms

当使用Brin索引时,同样查询耗时58ms。

gpadmin=# select count(*) from t1 where c1 > 10 and c1 < 1000;
count
-------
989
(1 row)
​
Time: 58.739 ms

当使用Btree索引时,同样的查询耗时4ms。

gpadmin=# select count(*) from t1 where c1 > 10 and c1 < 1000;
count
-------
989
(1 row)
Time: 3.738 ms

考虑到Brin索引是一个范围索引,其具有一定的稀疏性,索引的精度在一些情况下不如Btree索引,上面的性能差距可以理解。虽然如此,我们也看到Brin索引相对于顺序扫描还是取得了巨大的性能提升,这也体现了Brin索引的价值。

04 结语

Brin索引作为一个新的索引类型,具有极具优势的磁盘空间表现以及优秀的查询性能表现,同时还具有比较好的索引更新性能,这些特性十分符合超大型数据表的要求,在现实应用中被大家广泛的使用,本文简单介绍了Brin索引及其实现,希望对大家理解索引有所帮助。

在这里插入图片描述


http://www.niftyadmin.cn/n/1446806.html

相关文章

hysbz 1036 树的统计Count(树链剖分)

题目链接&#xff1a;hysbz 1036 树的统计Count 题目大意&#xff1a;略。 解题思路&#xff1a;树链剖分线段树维护。 #include <cstdio> #include <cstring> #include <algorithm>using namespace std;const int maxn 30005; const int INF 0x3f3f3f3f;…

python机器学习——聚类分析简介

聚类分析数据聚类理论理论一、聚类定义二、聚类与分类区别三、聚类分析的目的四、聚类主要方法数据聚类理论理论 一、聚类定义 数据聚类 ( Cluster analysis )是指根据数据的内在性质将数据分成一些聚合类&#xff0c;每一聚合类中的元素尽可能具有相同的特性&#xff0c;不同…

什么是3G(转)

3G是英文3rd Generation的缩写&#xff0c;指第三代移动通信技术。相对第一代模拟制式手机(1G)和第二代GSM、TDMA等数字手机(2G)&#xff0c;第三代手机一般地讲&#xff0c;是指将无线通信与国际互联网等多媒体通信结合的新一代移动通信系统。它能够处理图像、音乐、视频流等多…

@RequestBody接收不到前端传递过来的json数据

uniRequest.post(/orderParking,{parkingRecord:this.ParkingRecord})我刚开始只是写RequestBody ParkingRecord parkingRecord 一直获取的都是null, 直到用了Map标签才终于获取到参数了 RequestMapping(value "/orderParking",produces"application/json"…

要懂Greenplum索引,心里得有B树!

了解更多Greenplum技术干货&#xff0c;欢迎访问Greenplum中文社区网站 7月24日&#xff0c;Greenplum原厂内核研发马洪旭和大家直播分享了《深入浅出Greenplum内核》系列直播的第四期《Greenplum内核揭秘之B树索引》。相关视频已上传至Greenplum中文社区B站频道&#xff0c;戳…

python机器学习——Kmeans聚类

Kmeans聚类聚类基本思想Kmeans 介绍python 实现参考聚类基本思想 背景&#xff1a; 由于获取带有标签的数据成本比较高&#xff08;因为需要人工标记&#xff09;&#xff0c;而没有标签的数据却很容易获得。如果我们可以根据样本自身的属性或者说特征&#xff0c;给这写样本进…

秒杀系统架构

一、秒杀业务为什么难做 1&#xff09;im系统&#xff0c;例如qq或者微博&#xff0c;每个人都读自己的数据&#xff08;好友列表、群列表、个人信息&#xff09;&#xff1b; 2&#xff09;微博系统&#xff0c;每个人读你关注的人的数据&#xff0c;一个人读多个人的数据&…

让网站反向连接尽在你的掌握之中(转)

我们都知道&#xff0c;网站的反相链接数量&#xff0c;决定了网站的Link Popularity——当然&#xff0c;反相链接的质量也同样重要——从而最终影响到网站在搜索引擎中的排名。因此&#xff0c;在网站优化过程中&#xff0c;随时掌握有哪些网站、有多少网站建立了指向我们网站…