背景
从PostgreSQL 10 开始,社区保持每年一个大版本的节奏,表现出了超强的社区活力和社区创造力。
在2020-05-21 这个特殊的日子里,PostgreSQL 全球开发组宣布PostgreSQL 13 的Beta 1 正式对外开放,可提供下载。这个版本包含将来PostgreSQL 13正式版本中的所有特性和功能,当然一些功能的细节在正式版本发布时可能会有些变化。下面我们将详细了解下PostgreSQL 13 版本新的特性和功能。
PostgreSQL 13 新增特性
在社区的对外发布的文档(https://www.postgresql.org/about/news/2040/),把PostgreSQL 13 的新增特性分为了几部分:
数据库功能相关
数据库运维管理相关
数据库安全性相关
其他亮点
我们也按照这几部分来详细介绍,并对一些功能做一些实际的测试,看下具体的效果。
数据库功能相关
在PostgreSQL 13 版本中有许多地方的改进来实现性能的提升,同时对应用开发人员来说,应用开发更加容易。
B树索引优化
表的列如果不是唯一的,可能会有很多相同的值,对应的B树索引也会有很多重复的索引记录。在PostgreSQL 13 中B树索引借鉴了GIN 索引的做法,将相同的Key 指向的对应行的ctid 链接起来。这样既减小了索引的大小,又减少了很多不必要的分裂,提高了索引的检索速度,我们把该优化称为B树索引的deduplicate 功能。另外,B树索引的deduplicate 功能是异步进行的,只有在B 树索引需要分裂的时候才会去做该操作,减少了该功能的日常开销。
B树索引的deduplicate 功能的使用方法如下:
可以看出,需要在创建B 树索引的时候增加deduplicate_items 存储参数为on(PG 13 中index 该存储参数目前默认为on),deduplicate 功能才会开启。
为了测试deduplicate 功能的效果,我们拿12 和13 版本做了下对比。PostgreSQL 12 含有
PostgreSQL 13:
可以看出:
PostgreSQL 13 和PostgreSQL 12相比,相同类型且没有重复值的B树索引,大小相同。
PostgreSQL 13 和PostgreSQL 12相比,相同类型且有大量重复值的B树索引更小。
PostgreSQL 13 和PostgreSQL 12相比,如果索引有大量重复值且执行计划走index only scan 的话,需要读取的索引页更少,效率更高。
除了数据级别的重复之外,因为PostgreSQL 的MVCC 实现会带来B树索引中有重复Key 的不同快照,13 版本中B树索引的deduplicate 功能同样对其有效。不过有一定的局限:
text, varchar, char 类型数据,如果使用了特殊的collation,则可能需要大小写和口音不同来定义数据是否相等,无法使用deduplicate 功能。
numeric 类型数据无法使用deduplicate 功能,因为numeric 类型需要结合不同的展示范围才能定义数值是否相等。
jsonb 类型数据无法使用deduplicate 功能,因为jsonb B树操作类型内部使用了numeric 类型。
float4 和float8 类型数据无法使用该优化,因为在这两个类型中-0 和0 数值被认为是相等的。
总的来说,这些不支持的数据类型主要是因为判断他们Key 是否相同不能只通过数值来判断,还需要额外的条件。
B树索引是PostgreSQL 中默认的索引类型,社区几个大版本都对其占用空间和执行效率不断地进行优化。其实,PostgreSQL 12 中已经对B 树索引做了一定的deduplicate 优化,详见之前的文章,13 版本是对该优化的进一步完善和增强。
增量排序
PostgreSQL 13 版本增加了增量排序。这个优化其实起源于一个很朴素的算法,当对一组数据集(X,Y)按照X、Y两列进行组合排序,如果当前数据集已经按X 列进行了排序,如下:
(1, 5)
(1, 2)
(2, 9)
(2, 1)
(2, 5)
(3, 3)
(3, 7)
这时,只需要对数据集按照X 分组,并在每组中对Y 列继续排序,就可以得到按照X、Y 排序的结果集,如下:
(1, 5) (1, 2)
(2, 9) (2, 1) (2, 5)
(3, 3) (3, 7)
=====================
(1, 2)
(1, 5)
(2, 1)
(2, 5)
(2, 9)
(3, 3)
(3, 7)
这种算法的好处是显而易见的,特别是对大的数据集来说,这样会减少每次排序的数据量,这里可以通过一定的策略控制让每次排序的数据量更适应当前设置的work_mem。另外一方面,在PostgreSQL 的瀑布模型执行器中,我们可以不用全部数据的排序结果就可以得到部分结果集,非常适合带Limit 关键字的top-N 的查询。
当然,在数据库的优化器中,要远比上面的情况复杂的多。如果每个分组较大,分组数量较少的话,增量排序的代价会比较高。如果每个分组较小,分组数量较多的话,我们使用增量排序利用之前排好序的结果需要的代价比较小。为了中和两者的影响,PostgreSQL 13 中采用了2种模式:
抓取相对安全的行数不需要检查之前的排序键进行全排,这里的安全是基于一些代价的考虑。
抓取所有的行,基于之前的排序键上再进行分组排序。
PostgreSQL 优化器是优先会去使用模式1,然后启发式地使用模式2。
增量排序具体的使用方法以及开启关闭该功能的执行计划对比如下:
postgres=# create table t (a int, b int, c int);
CREATE TABLE
postgres=# insert into t select mod(i,10),mod(i,10),i from generate_series(1,10000) s(i);
INSERT 0 10000
postgres=# create index on t (a);
CREATE INDEX
postgres=# analyze t;
ANALYZE
postgres=# set enable_incrementalsort = off;
SET
postgres=# explain analyze select a,b,sum(c) from t group by 1,2 order by 1,2,3 limit 1;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------
Limit (cost=231.50..231.50 rows=1 width=16) (actual time=2.814..2.815 rows=1 loops=1)
-> Sort (cost=231.50..231.75 rows=100 width=16) (actual time=2.813..2.813 rows=1 loops=1)
Sort Key: a, b, (sum(c))
Sort Method: top-N heapsort Memory: 25kB
-> HashAggregate (cost=230.00..231.00 rows=100 width=16) (actual time=2.801..2.804 rows=10 loops=1)
Group Key: a, b
Peak Memory Usage: 37 kB
-> Seq Scan on t (cost=0.00..155.00 rows=10000 width=12) (actual time=0.012..0.951 rows=10000 loops=1)
Planning Time: 0.169 ms
Execution Time: 2.858 ms
(10 rows)
postgres=# set enable_incrementalsort = on;
SET
postgres=# explain analyze select a,b,sum(c) from t group by 1,2 order by 1,2,3 limit 1;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=133.63..146.52 rows=1 width=16) (actual time=1.177..1.177 rows=1 loops=1)
-> Incremental Sort (cost=133.63..1422.16 rows=100 width=16) (actual time=1.176..1.176 rows=1 loops=1)
Sort Key: a, b, (sum(c))
Presorted Key: a, b
Full-sort Groups: 1 Sort Method: quicksort Average Memory: 25kB Peak Memory: 25kB
-> GroupAggregate (cost=120.65..1417.66 rows=100 width=16) (actual time=0.746..1.158 rows=2 loops=1)
Group Key: a, b
-> Incremental Sort (cost=120.65..1341.66 rows=10000 width=12) (actual time=0.329..0.944 rows=2001 loops=1)
Sort Key: a, b
Presorted Key: a
Full-sort Groups: 3 Sort Method: quicksort Average Memory: 28kB Peak Memory: 28kB
Pre-sorted Groups: 3 Sort Method: quicksort Average Memory: 71kB Peak Memory: 71kB
-> Index Scan using t_a_idx on t (cost=0.29..412.65 rows=10000 width=12) (actual time=0.011..0.504 rows=3001 loops=1)
Planning Time: 0.164 ms
Execution Time: 1.205 ms
(15 rows)
分区表增强
PostgreSQL 13 版本中对PostgreSQL中的分区表功能有多处增强,包括在多分区表中进行直接连接,以减少总的查询执行时间。分区表现在支持BEFORE关键字的行级触发器,并且现在一个分区表也可以通过逻辑复制的方式进行复制, 而不必像以前那个发布单个分区表。
其他
支持了带有OR选项或是IN/ANY选项的查询使用扩展的统计信息(通过 CREATE STATISTICS 创建),这样就可以得到更合理的查询规划和性能提升。
支持大数据集查询时,hashagg 使用磁盘存储(enable_hashagg_disk=on)。在之前的版本中,如果hashagg 使用的内存预测要大于work_mem,则不使用hashagg。
对jsonpath的查询增加了.datetime()函数, 它可以将日期或时间的字符串自动转换为对应的PostgreSQL日期或时间数据类型。
支持 gen_random_uuid() 内置函数生成随机的UUID,而不依赖外部插件。
数据库管理并行VACUUM
PostgreSQL 13 版本中最令人期待的特性之一就是并行VACUUM。在之前的版本中,每个表的VACUUM 操作并不能并行,当表比较大的时候,VACUUM 的时间就会很长。在PostgreSQL 13中,支持了对索引的并行VACUUM,目前有很多的限制:
目前仅限于索引,每个索引可以分配一个vacuum worker。
不支持在加上FULL选项后使用。
只有在至少有2个以上索引的表上使用parallel选项才有效。
我们使用并行VACUUM 和12 版本进行了一个简单的对比,如下:
=================================PG 13 parallel vacuum===============================
postgres=# create table testva(id int,info text);
CREATE TABLE
Time: 2.334 ms
postgres=# insert into testva select generate_series(1,1000000),md5(random()::text);
INSERT 0 1000000
Time: 1448.098 ms (00:01.448)
postgres=# create index idx_testva on testva(id);
CREATE INDEX
Time: 364.988 ms
postgres=# create index idx_testva_info on testva(info);
CREATE INDEX
Time: 873.416 ms
postgres=# vacuum (parallel 4) testva;
VACUUM
Time: 114.846 ms
=================================PG 12 normal vacuum===============================
postgres=# create table testva(id int,info text);
CREATE TABLE
Time: 5.817 ms
postgres=# insert into testva select generate_series(1,1000000),md5(random()::text);
INSERT 0 1000000
Time: 3023.958 ms (00:03.024)
postgres=# create index idx_testva on testva(id);
CREATE INDEX
Time: 631.632 ms
postgres=# create index idx_testva_info on testva(info);
CREATE INDEX
Time: 1374.849 ms (00:01.375)
postgres=# vacuum testva;
VACUUM
Time: 216.944 ms
http://xinguang.sctcbmw.cn/ghua/ http://fuyang.tjtcbmw.cn/jingzhou/ http://ty.cqtcxxw.cn/wh/ https://fenlei.tiancebbs.cn/fjx/ https://fenlei.tiancebbs.cn/twjm/ http://taiying.njtcbmw.cn/ygjz/ http://nalei.zjtcbmw.cn/hywl/ http://taiying.njtcbmw.cn/glpx/ http://taiying.njtcbmw.cn/kezilesu/ http://nalei.zjtcbmw.cn/smxc/ http://tuiguang.hntcxxw.cn/hbts/ https://xinghuazhen.tiancebbs.cn/ https://aihuishou.tiancebbs.cn/bpcq/ http://shengshun.njtcbmw.cn/kelamayi/ http://huaguang.jxtcbmw.cn/twtd/ https://nankang.tiancebbs.cn/ http://wutai.cqtcxxw.cn/qinzhou/
项燕与项羽是什么关系:https://www.nanss.com/wenti/18305.html 芒果的功效与作用及营养:https://www.nanss.com/yinshi/19757.html 学生党员个人总结:https://www.nanss.com/xuexi/20071.html 中学生写事作文:https://www.nanss.com/xuexi/20097.html 文科就业前景最好的十大专业:https://www.nanss.com/xuexi/20151.html 桂附地黄丸的作用与功效:https://www.nanss.com/yinshi/19722.html 南非是哪个国家:https://www.nanss.com/wenti/19396.html 百分数的认识教学反思:https://www.nanss.com/gongzuo/20091.html 思政课心得体会:https://www.nanss.com/xuexi/19984.html 运动补水:https://www.nanss.com/shenghuo/19498.html 什么是车损险:https://www.nanss.com/wenti/18340.html 欢度春节作文:https://www.nanss.com/xuexi/19150.html 初中教师个人工作总结:https://www.nanss.com/gongzuo/19301.html 告别2023迎接2024:https://www.nanss.com/yulu/19113.html 芋头的功效与作用:https://www.nanss.com/yinshi/19724.html 新年计划:https://www.nanss.com/gongzuo/19370.html 会议方案:https://www.nanss.com/gongzuo/18682.html 一平方千米等于多少平方米:https://www.nanss.com/shenghuo/19909.html 工作规划怎么写:https://www.nanss.com/gongzuo/19317.html 事业单位绩效考核:https://www.nanss.com/gongzuo/19629.html 销售部管理制度:https://www.nanss.com/gongzuo/19080.html 草船借箭的故事简述:https://www.nanss.com/xuexi/18993.html 工业三废是指什么:https://www.nanss.com/wenti/18478.html 上尉是什么级别:https://www.nanss.com/wenti/19422.html 借贷合同:https://www.nanss.com/shenghuo/18789.html 安全先进个人材料:https://www.nanss.com/gongzuo/19300.html 水浒传读后感800字:https://www.nanss.com/xuexi/20020.html 党员自我评价:https://www.nanss.com/xuexi/19223.html 童年读书笔记1000字:https://www.nanss.com/xuexi/19611.html 爱眼护眼宣传语:https://www.nanss.com/wenan/18423.html