好吧,那就是每年这时候我们再次看看PostgreSQL的最新版本。
作为传统规定,在Percona,团队给出的列表特性来写。雷竞技下载官网我碰巧是一个非常基本的,我可能会增加,重要的功能即选择不同。
在进入细节之前,我想提一些说明如何的结果导出博客:
- 相当小的表和一个简单的架构。
- 因为这演示了在一个相对低功率系统,真正的指标有可能显著大于所证明。
PostgreSQL选择不同的条款是什么?
对于那些新postgres, ANSI SQL标准,选择不同的语句可以消除重复的行从结果集匹配指定的表达式。从每组(PostgreSQL的保持一个条目行重复。)
例如,得到下表:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
表
t_ex
;
c1
|
c2
- - -
- - -
+
- - -
- - -
2
|
B
4
|
C
6
|
一个
2
|
C
4
|
B
6
|
B
2
|
一个
4
|
B
6
|
C
2
|
C
|
这个SQL语句返回这些记录过滤中的惟一值列“c1”顺序:
|
1
|
选择
截然不同的
在(c1)*
从
t_ex;
|
注意,所显示的列c2, c1独特性返回第一个表中找到的值:
|
1
2
3
4
5
|
c1
|
c2
- - -
- - -
+
- - -
- - -
2
|
B
4
|
B
6
|
B
|
这个SQL语句返回这些记录过滤中惟一的值列“c2”
|
1
|
选择
截然不同的
在(c2)*
从
t_ex;
|
|
1
2
3
4
5
|
c1
|
c2
- - -
- - -
+
- - -
- - -
6
|
一个
2
|
B
4
|
C
|
当然,最后返回独特性为整个行:
|
1
|
选择
截然不同的
*
从
t_ex;
|
|
1
2
3
4
5
6
7
8
9
10
|
c1
|
c2
- - -
- - -
+
- - -
- - -
2
|
一个
6
|
B
4
|
C
2
|
B
6
|
一个
2
|
C
4
|
B
6
|
C
|
所以这是什么特别的新增强的独特的你问?答案是,这是并行!
在过去,只有一个CPU /过程被用来计算不同记录的数量。然而,postgres版15一个现在可以分解计算的任务并行运行多个数量的工人每个CPU分配给一个单独的进程。有许多运行时参数控制这种行为,但我们关注的是max_parallel_workers_per_gather。
PostgreSQL的条款例子:生成指标
让我们产生一些指标!
为了证明这种改进的性能三个表被创建的时候,没有索引,填充大约5000000条记录。注意每个表的列数即一、5和10个分别为:
|
1
2
3
4
|
表
“public.t1”
列
|
类型
|
排序
|
可以为空
|
默认的
- - -
- - -
- - -
- - -
+
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
+
- - -
- - -
- - -
- - -
- - - - - -
c1
|
整数
|
|
|
|
|
1
2
3
4
5
6
7
8
|
表
“public.t5”
列
|
类型
|
排序
|
可以为空
|
默认的
- - -
- - -
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
+
- - -
- - -
- - -
- - -
- - - - - -
c1
|
整数
|
|
|
c2
|
整数
|
|
|
c3
|
整数
|
|
|
c4
|
整数
|
|
|
c5
|
字符
不同
(
40
)
|
|
|
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
表
“public.t10”
列
|
类型
|
排序
|
可以为空
|
默认的
- - -
- - -
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
+
- - -
- - -
- - -
- - -
- - - - - -
c1
|
整数
|
|
|
c2
|
整数
|
|
|
c3
|
整数
|
|
|
c4
|
整数
|
|
|
c5
|
字符
不同
(
40
)
|
|
|
c6
|
整数
|
|
|
c7
|
整数
|
|
|
c8
|
整数
|
|
|
制备过程
|
整数
|
|
|
10大
|
整数
|
|
|
|
|
1
|
插入
成
t1
选择
generate_series
(
1
,
500年
)
;
|
|
1
2
3
4
5
6
7
8
9
10
11
|
插入
成
t10
选择
generate_series(1500)
,generate_series(500,1000)
,generate_series(1000,1500)
,(随机()* 100)::int
,generate_series(1500,2000)
,generate_series(2500,3000)
,generate_series(3000,3500)
,generate_series(3500,4000)
,generate_series(4000、4500);
|
|
1
2
3
4
5
6
|
列表
的
关系
模式
|
的名字
|
类型
|
老板
|
持久性
|
访问
方法
|
大小
|
- - -
- - -
- - -
- - -
+
- - -
- - -
- - -
+
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
+
- - -
- - -
- - -
- - -
+
公共
|
t1
|
表
|
postgres
|
永久
|
堆
|
173年
MB
|
公共
|
t10
|
表
|
postgres
|
永久
|
堆
|
522年
MB
|
公共
|
t5
|
表
|
postgres
|
永久
|
堆
|
404年
MB
|
|
下一步是将上述数据转储复制到以下版本的postgres:
|
1
2
3
4
5
6
7
8
|
PG
版本
pg96
pg10
pg11
pg12
pg13
pg14
pg15
|
postgres的二进制文件被编译从源和数据集群上创建相同的低功率硬件使用默认,不调谐的,运行时配置值。
一旦填充,bash脚本执行后生成的结果:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
# ! / bin / bash
为
v
在
96年
10
11
12
13
14
15
做
#运行解释analzye 5 x为了获得一致的数字
为
u
在
美元
(
seq
1
5
)
做
回声
v”——解释分析:pg ${},{你}X美元- - - - - -”
psql
- - - - - -
p
One hundred.
v美元
db01
- - - - - -
c
“解释分析选择不同的从t1 (c1) *”
>
t1
.pg
v美元
.explain
. txt
psql
- - - - - -
p
One hundred.
v美元
db01
- - - - - -
c
“从t5解释分析选择不同的*”
>
t5
.pg
v美元
.explain
. txt
psql
- - - - - -
p
One hundred.
v美元
db01
- - - - - -
c
“从t10解释分析选择不同的*”
>
t10
.pg
v美元
.explain
. txt
完成
完成
|
这里是结果:一个可以看到表变得越大所能达到的性能收益就越大。
PG版本 |
1列(t1),女士 |
5列(t5),女士 |
10列(t10),女士 |
pg96 |
3382年 |
9743年 |
20026年 |
pg10 |
2004年 |
5746年 |
13241年 |
pg11 |
1932年 |
6062年 |
14295年 |
pg12 |
1876年 |
5832年 |
13214年 |
pg13 |
1973年 |
2358年 |
3135年 |
pg14 |
1948年 |
2316年 |
2909年 |
pg15 |
1439年 |
1025年 |
1245年 |

查询计划
更有趣的一个方面的调查审核postgres的不同版本之间的查询计划。例如,单个列不同的查询计划是很相似,当然,无视上级执行时间之间的postgres分别9.6和15计划。
|
1
2
3
4
5
6
7
8
9
|
PG96
查询
计划
,
表
T1
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
独特的
(
成本
=
765185.42,790185.42
行
=
500年
宽度
=
4
)
(
实际
时间
=
2456.805,3381.230
行
=
500年
循环
=
1
)
- >
排序
(
成本
=
765185.42,777685.42
行
=
5000000
宽度
=
4
)
(
实际
时间
=
2456.804,3163.600
行
=
5000000
循环
=
1
)
排序
关键
:
c1
排序
方法
:
外部
合并
磁盘
:
68432 kb
- >
Seq
扫描
在
t1
(
成本
=
0.00,72124.00
行
=
5000000
宽度
=
4
)
(
实际
时间
=
0.055,291.523
行
=
5000000
循环
=
1
)
规划
时间
:
0.161
女士
执行
时间
:
3381.662
女士
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
PG15
查询
计划
,
表
T1
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
独特的
(
成本
=
557992.61,582992.61
行
=
500年
宽度
=
4
)
(
实际
时间
=
946.556,1411.421
行
=
500年
循环
=
1
)
- >
排序
(
成本
=
557992.61,570492.61
行
=
5000000
宽度
=
4
)
(
实际
时间
=
946.554,1223.289
行
=
5000000
循环
=
1
)
排序
关键
:
c1
排序
方法
:
外部
合并
磁盘
:
58720 kb
- >
Seq
扫描
在
t1
(
成本
=
0.00,72124.00
行
=
5000000
宽度
=
4
)
(
实际
时间
=
0.038,259.329
行
=
5000000
循环
=
1
)
规划
时间
:
0.229
女士
JIT
:
功能
:
1
选项
:
内联
真正的
,
优化
真正的
,
表达式
真正的
,
变形
真正的
时机
:
一代
0.150
女士
,
内联
31.332
女士
,
优化
6.746
女士
,
发射
6.847
女士
,
总
45.074
女士
执行
时间
:
1438.683
女士
|
真正的不同出现不同的列的数量增加时,如表t10演示了通过查询。可以看到并行在行动!
|
1
2
3
4
5
6
7
8
9
|
PG96
查询
计划
,
表
T10
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
独特的
(
成本
=
1119650.30,1257425.30
行
=
501000年
宽度
=
73年
)
(
实际
时间
=
14257.801,20024.271
行
=
50601年
循环
=
1
)
- >
排序
(
成本
=
1119650.30,1132175.30
行
=
5010000
宽度
=
73年
)
(
实际
时间
=
14257.800,19118.145
行
=
5010000
循环
=
1
)
排序
关键
:
c1
,
c2
,
c3
,
c4
,
c5
,
c6
,
c7
,
c8
,
制备过程
,
10大
排序
方法
:
外部
合并
磁盘
:
421232 kb
- >
Seq
扫描
在
t10
(
成本
=
0.00,116900.00
行
=
5010000
宽度
=
73年
)
(
实际
时间
=
0.073,419.701
行
=
5010000
循环
=
1
)
规划
时间
:
0.352
女士
执行
时间
:
20025.956
女士
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
PG15
查询
计划
,
表
T10
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
HashAggregate
(
成本
=
699692.77,730144.18
行
=
501000年
宽度
=
73年
)
(
实际
时间
=
1212.779,1232.667
行
=
50601年
循环
=
1
)
集团
关键
:
c1
,
c2
,
c3
,
c4
,
c5
,
c6
,
c7
,
c8
,
制备过程
,
10大
计划
分区
:
16
批次
:
17
内存
使用
:
8373 kb
磁盘
使用
:
2976 kb
- >
收集
(
成本
=
394624.22,552837.15
行
=
1002000
宽度
=
73年
)
(
实际
时间
=
1071.280,1141.814
行
=
151803年
循环
=
1
)
工人
计划
:
2
工人
推出了
:
2
- >
HashAggregate
(
成本
=
393624.22,451637.15
行
=
501000年
宽度
=
73年
)
(
实际
时间
=
1064.261,1122.628
行
=
50601年
循环
=
3
)
集团
关键
:
c1
,
c2
,
c3
,
c4
,
c5
,
c6
,
c7
,
c8
,
制备过程
,
10大
计划
分区
:
16
批次
:
17
内存
使用
:
8373 kb
磁盘
使用
:
15176 kb
工人
0
:
批次
:
17
内存
使用
:
8373 kb
磁盘
使用
:
18464 kb
工人
1
:
批次
:
17
内存
使用
:
8373 kb
磁盘
使用
:
19464 kb
- >
平行
Seq
扫描
在
t10
(
成本
=
0.00,87675.00
行
=
2087500
宽度
=
73年
)
(
实际
时间
=
0.072,159.083
行
=
1670000
循环
=
3
)
规划
时间
:
0.286
女士
JIT
:
功能
:
31日
选项
:
内联
真正的
,
优化
真正的
,
表达式
真正的
,
变形
真正的
时机
:
一代
3.510
女士
,
内联
123.698
女士
,
优化
200.805
女士
,
发射
149.608
女士
,
总
477.621
女士
执行
时间
:
1244.556
女士
|
提高了性能
性能增强是由更新postgres运行时参数max_parallel_workers_per_gather。在集群新初始化默认值是2。下面的表格显示,它很快成为收益递减的问题由于测试硬件本身的限制功能。
POSTGRES版本15
max_parallel_workers_per_gather |
1列(t1) |
5列(t5) |
10列(t10) |
2 |
1439年 |
1025年 |
1245年 |
3 |
1464年 |
875年 |
1013年 |
4 |
1391年 |
858年 |
977年 |
6 |
1401年 |
846年 |
1045年 |
8 |
1428年 |
856年 |
993年 |

对索引
性能改进是<强大的>不强大的>意识到当索引查询计划中说明的应用。
PG15、表T10(10个不同的列)max_parallel_workers_per_gather = 4:
|
1
2
3
4
5
6
7
8
9
10
11
|
查询
计划
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - - -
独特的
(
成本
=
0.43,251344.40
行
=
501000年
宽度
=
73年
)
(
实际
时间
=
0.060,1240.729
行
=
50601年
循环
=
1
)
- >
指数
只有
扫描
使用
t10_c1_c2_c3_c4_c5_c6_c7_c8_c9_c10_idx
在
t10
(
成本
=
0.43,126094.40
行
=
5010000
宽度
=
73年
)
(
实际
时间
=
0.058,710.780
行
=
5010000
循环
=
1
)
堆
获取
:
582675年
规划
时间
:
0.596
女士
JIT
:
功能
:
1
选项
:
内联
假
,
优化
假
,
表达式
真正的
,
变形
真正的
时机
:
一代
0.262
女士
,
内联
0.000
女士
,
优化
0.122
女士
,
发射
2.295
女士
,
总
2.679
女士
执行
时间
:
<
强大的
>
1249.391
女士
<
/
强大的
>
|
最后的想法
运行不同的多个cpu性能是一个大的进步。但记住的风险减少性能当你增加的数量max_parallel_workers_per_gather和你接近你的硬件的限制。调查显示,在正常情况下,查询计划可能决定使用索引,而不是平行的工人。为了解决这个问题的方法之一是考虑禁用等运行时参数enable_indexonlyscan和enable_indexscan。最后,别忘了运行解释分析,以理解发生了什么。
得到Pe雷竞技下载官网rcona支持PostgreSQL
雷竞技下载官网Percona支持PostgreSQL数据库的dba和开发人员寻求帮助。
额外的Percona支雷竞技下载官网持和资源包括:







好,谢谢你。
我看到查询溢出到磁盘上,从查询计划:
合并排序方法:外部磁盘:68432 kb
这将是有趣的计时结果如果机器配置了足够的内存和/或合适的work_mem等参数,以便不会发生,这将提供一个更有代表性的使用。否则磁盘活动沼泽几乎所有其他因素。
嗨,这是一个很好的点!
我总是第二猜测自己我应该执行多少调优每当我做一个调查。随着时间的流逝,我意识到只要方法和假设是那么希望足够记录信息,它可以使用至少一个起点满足读者的需求。
希望这有助于
这是一个很好的观点。我认为只要有足够的信息允许其复制然后人们可以希望takie他们阅读作为起点为他们自己的调查。
你写“这个SQL语句返回这些记录过滤中的惟一值列“c1”顺序:选择不同的(c1) * t_ex;”。
SQL标准是开放的,如果不同的返回数据排序或随机因为这我实现的依赖。Oracle使用返回值从“独特”和“集团”排序,但从版本9。x这不是真的不再因为他们开始使用一个散列并行函数之后,这个值是排序。
官方声明如果你需要排序的数据使用一个“命令”。
值得一提的是,在选择不同的规模没有人使用,而是快速近似像HyperLogLog CitusData postgresql-hll的实现方法:
https://github.com/citusdata/postgresql-hll
不幸的是,不是太多人知道HyperLogLog即使它已经存在多年。