巧用dblink 实现多进程并行查询
概述
对于分区表的大数据统计分析,由于数据量巨大,往往需要采用并行。但是数据库并行的效率相比分进程分表统计还是有比较大的差距。本文通过巧用dblink,实现分进程分分区统计数据。
例子
kingbase=# \d t751
分区表 "public.t751"
栏位 | 类型 | 校对规则 | 可空的 | 预设
------+-----------------------------+----------+----------+------
id | bigint | | not null |
code | text | | |
c1 | timestamp without time zone | | |
c2 | text | | |
c3 | numeric | | |
c4 | integer | | |
c5 | integer | | |
c6 | integer | | |
v2 | numeric | | |
v3 | timestamp without time zone | | |
分区键值: HASH (c4, c5, c6)
分区的数量:1000(可以使用 \d+ 来列出它们)
表空间:"nvmtbs01" kingbase=# select pg_size_pretty(sum(pg_relation_size(relid))) from pg_partition_tree('t751');
pg_size_pretty
----------------
20 GB
并行方式访问
kingbase=# explain analyze select c4, c5, c6, sum(v2) v2 from t751 group by c4, c5, c6;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------
Finalize GroupAggregate (cost=5656234.57..14706860.46 rows=8000000 width=44) (actual time=15764.781..19110.336 rows=11781 loops=1)
Group Key: t751_872.c4, t751_872.c5, t751_872.c6
-> Gather Merge (cost=5656234.57..13806860.46 rows=64000000 width=44) (actual time=15764.142..19103.239 rows=11902 loops=1)
Workers Planned: 8
Workers Launched: 7
-> Partial GroupAggregate (cost=5655234.43..5911484.32 rows=8000000 width=44) (actual time=15478.852..18479.480 rows=1488 loops=8)
Group Key: t751_872.c4, t751_872.c5, t751_872.c6
-> Sort (cost=5655234.43..5686484.41 rows=12499991 width=22) (actual time=15478.239..17066.239 rows=12500000 loops=8)
Sort Key: t751_872.c4, t751_872.c5, t751_872.c6
Sort Method: quicksort Memory: 1408511kB
Worker 0: Sort Method: quicksort Memory: 1371267kB
Worker 1: Sort Method: quicksort Memory: 1364497kB
Worker 2: Sort Method: quicksort Memory: 1374769kB
Worker 3: Sort Method: quicksort Memory: 1355381kB
Worker 4: Sort Method: quicksort Memory: 1352989kB
Worker 5: Sort Method: quicksort Memory: 1343974kB
Worker 6: Sort Method: quicksort Memory: 1386845kB
-> Parallel Append (cost=0.00..3156369.51 rows=12499991 width=22) (actual time=0.034..5045.596 rows=12500000 loops=8)
-> Parallel Seq Scan on t751_872 (cost=0.00..5849.56 rows=81756 width=22) (actual time=0.025..60.070 rows=196215 loops=1)
-> Parallel Seq Scan on t751_470 (cost=0.00..5753.10 rows=80410 width=22) (actual time=0.068..73.100 rows=192984 loops=1)
...
-> Parallel Seq Scan on t751_416 (cost=0.00..556.80 rows=10380 width=22) (actual time=0.009..5.736 rows=17646 loops=1)
-> Parallel Seq Scan on t751_885 (cost=0.00..315.77 rows=5877 width=22) (actual time=0.010..2.460 rows=9991 loops=1)
Planning Time: 26.450 ms
Execution Time: 19180.545 ms
注意:这里实际采用的是groupagg , 如果采用hashagg,执行效率会高很多
使用dblink方式
创建函数
create or replace function f_t_part(para int default 0)
returns table
(
c4 int,
c5 int,
c6 int,
v2 numeric
)
language plpgsql
immutable
parallel safe
as
$$
declare
vtabnam text;
atabnam text[];
begin
perform dblink_disconnect(conn)
from unnest(dblink_get_connections()) conn; perform dblink_connect('conn_' || sn, 'dbname=' || current_database())
from generate_series(1, para) sn; if para <= 0 then
for vtabnam in select relid from pg_partition_tree('t751')
loop
for c4,c5,c6,v2 in execute format('select c4, c5, c6, sum(v2) v2 from only %s group by c4, c5, c6 ;',vtabnam)
loop
return next ;
end loop;
end loop;
else
for atabnam in select string_to_array(string_agg(relid, ','), ',') relid
from pg_partition_tree('t751') with ordinality
, lateral ( select ordinality / para sn)
where isleaf
group by sn
loop perform dblink_is_busy(conn) = 0 from unnest(dblink_get_connections()) conn; perform conn,tabnam, dblink_send_query(conn,format('select c4, c5, c6, sum(v2) v2 from only %s group by c4, c5, c6 ;',tabnam)) sq
from (select unnest(dblink_get_connections()) conn, unnest(atabnam) tabnam) v
where tabnam is not null; for c4,c5,c6,v2 in
select tab.* from unnest(dblink_get_connections()) conn , dblink_get_result(conn) as tab(c4 int, c5 int, c6 int, v2 numeric)
loop
return next ;
end loop;
end loop;
end if; perform dblink_disconnect(conn) from unnest(dblink_get_connections()) conn;
return;
end;
$$;
执行效率
ingbase=# explain analyze select * from ft751_01();
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------
Function Scan on ft751_01 (cost=0.25..10.25 rows=1000 width=44) (actual time=32738.962..32739.288 rows=11781 loops=1)
Planning Time: 0.055 ms
Execution Time: 32741.655 ms
(3 行记录) kingbase=# explain analyze ^Jselect * from ft751_01(16);
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------
Function Scan on ft751_01 (cost=0.25..10.25 rows=1000 width=44) (actual time=5397.644..5398.189 rows=11781 loops=1)
Planning Time: 0.044 ms
Execution Time: 5398.887 ms
结论
实际验证,二者性能上差距并不大。用dblink 方式主要是可以更灵活的使用并行数量。这里的目的主要是向大家提供灵活使用并行的一种方法。
巧用dblink 实现多进程并行查询的更多相关文章
- Python:多进程并行编程与进程池
Python的并行编程可以采用multiprocessing或mpi4py模块来完成. multiprocessing是Python标准库中的模块,实现了共享内存机制,也就是说,可以让运行在不同处理器 ...
- Oracle并行查询出错
1.错误描写叙述 ORA-12801: 并行查询服务器P007中发出错误信号 ORA-01722:无效数字 12801.00000 -"error signaled in parallel ...
- SQL调优(SQL TUNING)并行查询提示(Hints)之pq_distribute的使用
pq_distribute提示通常被用于提升数据仓库中分区表间的连接操作性能. pq_distribute提示允许你确定参与连接的表数据行在生产和消费并行查询服务进程间如何分配. pq_distrib ...
- PostgreSQL9.6的新特性并行查询
PostgreSQL在2016年9月发布了9.6版本,在该版本中新增了并行计算功能,目前PG支持的并行查询主要是顺序扫描(Sequencial Scans),并且支持部分链接查询(join)和聚合(a ...
- 【Oracle】 并行查询
所谓并行执行,是指能够将一个大型串行任务(任何DML,一般的DDL)物理的划分为叫多个小的部分,这些较小的部分可以同时得到处理.何时使用并行执行:1.必须有一个非常大的任务 2.必须有充足的资源(CP ...
- KingbaseES 并行查询
背景:随着硬件技术的提升,磁盘的IO能力及CPU的运算能力都得到了极大的增强,如何充分利用硬件资源为运算加速,是数据库设计过程中必须考虑的问题.数据库是IO和CPU密集型的软件,大规模的数据访问需要大 ...
- dblink嵌套场景下 查询出现:ORACLE ORA-00600错误的解决
前段时间在做oracle查询的时候遇到了一个非常奇怪的现象,现将现象和解决过程记录下来,以备查看: 环境描述:A数据库通过dblink访问B数据库的视图,B数据库的视图的数据是通过B的dblink连接 ...
- 基于MongoDB分布式存储进行MapReduce并行查询
中介绍了如何基于Mongodb进行关系型数据的分布式存储,有了存储就会牵扯到查询.虽然用普通的方式也可以进行查询,但今天要介绍的是如何使用MONGODB中提供的MapReduce功能进行查询. ...
- 并行查询提高sql查询速度
新项目在使用Oracle开发中遇到测试库千万级数据导致数据慢,除去加索引和存储过程可以明显提速外,使用并行也可以提速 select /*+parallel(a,8)*/ a.* from a 加上/* ...
- SQLite中使用CTE巧解多级分类的级联查询
在最近的项目中使用ActiveReports报表设计器设计一个报表模板时,遇到一个多级分类的难题:需要将某个部门所有销售及下属部门的销售金额汇总,因为下属级别的层次不确定,所以靠拼接子查询的方式显然是 ...
随机推荐
- Python 潮流周刊第 39 期(摘要)
本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...
- 时序数据库timescaleDB安装
一:前言相关 环境:Red Hat 8.3.1-5安装程序:PostgreSQL 14.1,TimescaleDB 2.5.1,cmake3.22.1PostgreSQL编译安装需要cmake3.4以 ...
- docker中container相关命令
1.以tomcat镜像为例运行tomcat容器(运行tomcat实例) docker run tomcat 2.宿主机端口与容器端口进行映射 -p docker run -p 8080(系统上外部端口 ...
- 【LeetCode二叉树#11】最大二叉树(构造二叉树)
最大二叉树 力扣题目地址(opens new window) 给定一个不含重复元素的整数数组.一个以此数组构建的最大二叉树定义如下: 二叉树的根是数组中的最大元素. 左子树是通过数组中最大值左边部分构 ...
- springboot-@Async默认线程池导致OOM问题
目录 内存溢出的三种类型: 初步分析: 代码分析: 最终解决办法: 内存溢出的三种类型: 第一种OutOfMemoryError: PermGen space,发生这种问题的原意是程序中使用了大量的j ...
- Java 关于变量的赋值
1 /** 2 * 3 * @Description 4 * @author Bytezero·zhenglei! Email:420498246@qq.com 5 * @version 6 * @d ...
- C++ //提高编程 模板(泛型编程 STL) //模板不可以直接使用 它只是一个框架 //模板的通用并不是万能的 //语法 //template<typename T> //函数模板两种方式 //1.自动类型推导 必须推导出一致的数据类型T,才可以使用 //2.显示指定类型 模板必须确定出T的数据类型,才可以使用
1 //C++提高编程 模板(泛型编程 STL) 2 //模板不可以直接使用 它只是一个框架 3 //模板的通用并不是万能的 4 //语法 5 //template<typename T> ...
- Java面试挂在线程创建后续,不要再被八股文误导了!创建线程的方式只有1种
写在开头 在上篇博文中我们提到小伙伴去面试,面试官让说出8种线程创建的方式,而他只说出了4种,导致面试挂掉,在博文中也给出了10种线程创建的方式,但在文章的结尾我们提出:真正创建线程的方式只有1种,剩 ...
- sql99等值&&非等值查询
1 #二.sql99语法 2 /* 3 语法 4 SELECT 查询列表 5 FROM 表1 别名 [连接类型] 6 JOIN 表2 别名 7 on 连接条件 8 [where 筛选条件] 9 [gr ...
- 聊聊Web项目中的权限设计
一般的Web项目中都少不了登录这个环节,登录之后就需要跳转到首页,并且根据 当前用户的信息,获取到对应的菜单信息,可以操作的方法信息等等.这个只是针对于 操作权限,至于数据权限处理起来会更加复杂一些. ...