巧用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报表设计器设计一个报表模板时,遇到一个多级分类的难题:需要将某个部门所有销售及下属部门的销售金额汇总,因为下属级别的层次不确定,所以靠拼接子查询的方式显然是 ...
随机推荐
- 开年喜报!Walrus成功入选CNCF云原生全景图
近日,数澈软件 Seal (以下简称"Seal")旗下开源应用管理平台 Walrus 成功入选云原生计算基金会全景图(CNCF Landscape)并收录至 "App D ...
- Spring源码之spring事务
目录 Spring事务 事务自定义标签 自定义标签 解析标签 bean 的初始化 InfrastructureAdvisorAutoProxyCreator 获取增强方法 获取所有增强中内适用于当前方 ...
- Spring源码之bean的加载
目录 1. FactoryBean 的使用 2. 缓存中获取单例 bean: 3. 从 bean 实例获取对象, 4. 获取单例 bean (从缓存加载失败): 5. 创建 bean (createB ...
- 神经网络优化篇:详解TensorFlow
TensorFlow 先提一个启发性的问题,假设有一个损失函数\(J\)需要最小化,在本例中,将使用这个高度简化的损失函数,\(Jw= w^{2}-10w+25\),这就是损失函数,也许已经注意到该函 ...
- SpringBoot下Akka的简单使用
SpringBoot下Akka的简单使用 Akka框架实现一个异步消息传输,通过定义演员来处理业务逻辑. 首先引入依赖 <!-- akka --> <dependency> & ...
- 项目实战:Qt+iMax6生命探测仪(探测障碍物、静止目标、动态目标、生命目标、探测半径、探测前方雷达显示、动态目标轨迹显示、探测热力图、探测过程存储与回放)
若该文为原创文章,转载请注明原文出处本文章博客地址:https://blog.csdn.net/qq21497936/article/details/110994486长期持续带来更多项目与技术分享, ...
- django学习第十四天--Forms和ModelForm
Forms和ModelForm 进行数据校验,先看数据校验的过程 注册页面图解: 前端为了用户体验会做一些校验,不满足校验要求会报错 服务端也会对数据进行一些校验,不满足校验要求会报错 数据库也会对数 ...
- Docker的使用记录
开始 这是第一个尝试在Leanote上面编写文章,我觉得最重要的事情就是能够保证md文件是能够移植的,否则如果这个软件不靠谱的话,我还能把文章移动到别的地方去.所以先写一篇文章看看效果如何,方便不方便 ...
- Android---Android Studio项目目录结构分析.
1. .gradle 和.idea 这两个目录下放置的都是 Android Studio 自动生成的一些文件,我们无须关心,也不要去手 动编辑. 2. app 项目中的代码.资源等内容几乎都是放置在这 ...
- 3、mysql定位低效率执行SQL
可以通过以下两种方式定位执行效率较低的 SQL 语句. 慢查询日志 : 通过慢查询日志定位那些执行效率较低的 SQL 语句,用--log-slow-queries[=file_name]选项启动时,m ...