PostgreSQL中的partition-wise aggregation
时间:2019-10-10
本文章向大家介绍PostgreSQL中的partition-wise aggregation,主要包括PostgreSQL中的partition-wise aggregation使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
partition-wise aggregation允许对每个分区分别执行的分区表进行分组或聚合。如果GROUP BY子句不包括分区键,则只能在每个分区的基础上执行部分聚合,并且必须稍后执行最终处理。由于partitionwise分组或聚合可能在计划期间占用大量CPU时间和内存,因此默认设置为关闭。
通过变量enable_partitionwise_aggregate控制是否启用该特性。
创建一个分区表,用于测试:
create table pagg_t (a int, b int, c text, d int) partition by list(c); create table pagg_t_p1 partition of pagg_t for values in ('000', '001', '002', '003'); create table pagg_t_p2 partition of pagg_t for values in ('004', '005', '006', '007'); create table pagg_t_p3 partition of pagg_t for values in ('008', '009', '010', '011'); insert into pagg_t select i % 20, i % 30, to_char(i % 12, 'fm0000'), i % 30 from generate_series(0, 2999) i; analyze pagg_t;
postgres=# show enable_partitionwise_aggregate; off postgres=# explain (costs off) select c, sum(a), avg(b), count(*), min(a), max(b) from pagg_t group by c having avg(d) < 15 order by 1, 2, 3; Sort Sort Key: pagg_t_p1.c, (sum(pagg_t_p1.a)), (avg(pagg_t_p1.b)) -> HashAggregate Group Key: pagg_t_p1.c Filter: (avg(pagg_t_p1.d) < '15'::numeric) -> Append -> Seq Scan on pagg_t_p1 -> Seq Scan on pagg_t_p2 -> Seq Scan on pagg_t_p3 postgres=#
默认情况下,需要先分别扫描表的所有分区,将分区结果整合在一起(Append),然后执行哈希聚合(HashAggregate),最后进行排序(Sort)。
启用智能分区聚合功能,查看相同的聚合操作:
postgres=# set enable_partitionwise_aggregate=on; SET postgres=# show enable_partitionwise_aggregate; on postgres=# explain (costs off) select c, sum(a), avg(b), count(*), min(a), max(b) from pagg_t group by c having avg(d) < 15 order by 1, 2, 3; Sort Sort Key: pagg_t_p1.c, (sum(pagg_t_p1.a)), (avg(pagg_t_p1.b)) -> Append -> HashAggregate Group Key: pagg_t_p1.c Filter: (avg(pagg_t_p1.d) < '15'::numeric) -> Seq Scan on pagg_t_p1 -> HashAggregate Group Key: pagg_t_p2.c Filter: (avg(pagg_t_p2.d) < '15'::numeric) -> Seq Scan on pagg_t_p2 -> HashAggregate Group Key: pagg_t_p3.c Filter: (avg(pagg_t_p3.d) < '15'::numeric) -> Seq Scan on pagg_t_p3 postgres=#
可以看到,启用该功能之后,先针对表中的所有分区执行哈希聚合(HashAggregate),然后将结果整合在一起(Append),最后进行排序(Sort)。其中,分区级别的聚合可以并行执行,性能会更好。
如果GROUP BY子句中没有包含分区字段,只会基于分区执行部分聚合操作,然后再对结果进行一次最终的聚合。
以下查询使用字段 a 进行分组聚合:
postgres=# explain (costs off) select a, sum(b), avg(b), count(*), min(a), max(b) from pagg_t group by a having avg(d) < 15 order by 1, 2, 3; Sort Sort Key: pagg_t_p1.a, (sum(pagg_t_p1.b)), (avg(pagg_t_p1.b)) -> Finalize HashAggregate Group Key: pagg_t_p1.a Filter: (avg(pagg_t_p1.d) < '15'::numeric) -> Append -> Partial HashAggregate Group Key: pagg_t_p1.a -> Seq Scan on pagg_t_p1 -> Partial HashAggregate Group Key: pagg_t_p2.a -> Seq Scan on pagg_t_p2 -> Partial HashAggregate Group Key: pagg_t_p3.a -> Seq Scan on pagg_t_p3 postgres=#
由于字段 a 不是分区键,所以先执行分区级别的部分哈希聚合(Partial HashAggregate),聚合的结果中可能存在相同的分组(不同分区中的字段 a 存在相同的值),需要执行最终的哈希聚合(Finalize HashAggregate)操作。
原文地址:https://www.cnblogs.com/abclife/p/11648006.html
- crontab命令详解
- hdu----(4308)Saving Princess claire_(搜索)
- spark2 sql读取数据源编程学习样例1
- golang的一个分页方法
- spark2 sql读取json文件的格式要求
- 容器化RDS|调度策略
- Go语言并发编程总结
- hdu------(4302)Holedox Eating(树状数组+二分)
- spark2的SparkSession思考与总结2:SparkSession有哪些函数及作用是什么
- GO语言并发编程之互斥锁、读写锁详解
- spark2.2 SparkSession思考与总结1
- 【译】Spring 官方教程:Spring Security 架构
- hdu----(4301)Divide Chocolate(状态打表)
- hdu------(4300)Clairewd’s message(kmp)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 前端成神之路-CSS基础选择器
- 前端成神之路-CSS文字文本样式
- 前端成神之路-CSS(选择器、背景、特性)
- 前端成神之路-列表和表单
- 前端成神之路-HTML
- Windows下如何查看某个端口被占用,以及如何杀死某个进程
- VSCode插件Todo Tree如何忽略某些文件夹?
- Express新建项目与配置项目热加载
- selenium控制已打开的页面
- 盘点一下lua脚本和python的区别(基础)
- python识别视频黑屏或者低清晰度
- python在linux环境下安装skimage
- python3异步爬虫 ——aiohttp模板使用
- [PHP] 抽象工厂设计模式-创建型设计模式
- [javascript] 支付宝小程序网络GET请求