Greenplum 大宽表 OR 分层关系 - 大量nestloop,补齐其他字段的性能损耗

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 标签PostgreSQL , Greenplum , 宽表 , 关系 , 循环 , 性能背景GPDB中,使用关系存储,还是使用大宽表呢?关系存储,在查询其他表的内容时,需要JOIN补齐。JOIN可能需要重分布数据,维度表可以解决大量数据重分布的问题。

标签

PostgreSQL , Greenplum , 宽表 , 关系 , 循环 , 性能


背景

GPDB中,使用关系存储,还是使用大宽表呢?

关系存储,在查询其他表的内容时,需要JOIN补齐。JOIN可能需要重分布数据,维度表可以解决大量数据重分布的问题。

大宽表,则可能存在数据冗余的问题,但是不需要JOIN。

业务可以在两者之间权衡。

下面的例子是补齐字段的例子,虽然JOIN补齐内容的表只有一条记录,但是使用了嵌套循环,性能相差了几十倍。

postgres=# create table a (id int, info text, c1 int);    
NOTICE:  Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Greenplum Database data distribution key for this table.    
HINT:  The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.    
CREATE TABLE    
  
postgres=# create table b(c1 int, c2 int, c3 int, c4 int);    
NOTICE:  Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Greenplum Database data distribution key for this table.    
HINT:  The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.    
CREATE TABLE    
  
postgres=# insert into a select id, 'test', 1 from generate_series(1,10000000) t(id);    
INSERT 0 10000000    
postgres=# insert into b values (1,1,1,1);    
INSERT 0 1    
    
postgres=# explain analyze select count(*) from (select a.id,a.info,a.c1,b.c1,b.c2 from a cross join b where b.c2=1) t;    
                                                                           QUERY PLAN                                                                               
----------------------------------------------------------------------------------------------------------------------------------------------------------------    
 Aggregate  (cost=6738189.77..6738189.78 rows=1 width=8)    
   Rows out:  1 rows with 0.003 ms to first row, 0.007 ms to end, start offset by 26 ms.    
   ->  Gather Motion 33:1  (slice2; segments: 33)  (cost=6738189.41..6738189.76 rows=1 width=8)    
         Rows out:  33 rows at destination with 5.391 ms to first row, 1481 ms to end, start offset by 26 ms.    
         ->  Aggregate  (cost=6738189.41..6738189.42 rows=1 width=8)    
               Rows out:  Avg 1.0 rows x 33 workers.  Max 1 rows (seg0) with 0.005 ms to first row, 17 ms to end, start offset by 28 ms.    
               ->  Nested Loop  (cost=1.39..6713190.40 rows=303019 width=0)    
                     Rows out:  Avg 303030.3 rows x 33 workers.  Max 303531 rows (seg23) with 0.006 ms to first row, 30 ms to end, start offset by 28 ms.    
                     ->  Seq Scan on a  (cost=0.00..113451.03 rows=303019 width=0)    
                           Rows out:  Avg 303030.3 rows x 33 workers.  Max 303531 rows (seg23) with 0.004 ms to first row, 18 ms to end, start offset by 28 ms.    
                     ->  Materialize  (cost=1.39..1.72 rows=1 width=0)    
                           Rows out:  0 rows (seg0) with 1227 ms to end, start offset by 1507 ms.    
                           ->  Broadcast Motion 33:33  (slice1; segments: 33)  (cost=0.00..1.35 rows=1 width=0)    
                                 Rows out:  Avg 1.0 rows x 33 workers at destination.  Max 1 rows (seg0) with 24 ms to end of 2 scans, start offset by 53 ms.    
                                 ->  Seq Scan on b  (cost=0.00..1.01 rows=1 width=0)    
                                       Filter: c2 = 1    
                                       Rows out:  1 rows (seg27) with 0.125 ms to first row, 0.126 ms to end.    
 Slice statistics:    
   (slice0)    Executor memory: 437K bytes.    
   (slice1)    Executor memory: 525K bytes avg x 33 workers, 540K bytes max (seg27).    
   (slice2)    Executor memory: 385K bytes avg x 33 workers, 385K bytes max (seg0).    
 Statement statistics:    
   Memory used: 1280000K bytes    
 Optimizer status: legacy query optimizer    
 Total runtime: 1510.517 ms    
(25 rows)    

如果业务上先从单表查出内容,直接在结果中补齐,而不是JOIN,那么只需要75毫秒。

postgres=# explain analyze select count(*) from (select a.id,a.info,a.c1,1,1 from a where a.c1=1) t;    
                                                                         QUERY PLAN                                                                              
-------------------------------------------------------------------------------------------------------------------------------------------------------------    
 Aggregate  (cost=163449.41..163449.42 rows=1 width=8)    
   Rows out:  1 rows with 0.001 ms to first row, 0.008 ms to end, start offset by 1.746 ms.    
   ->  Gather Motion 33:1  (slice1; segments: 33)  (cost=163449.05..163449.40 rows=1 width=8)    
         Rows out:  33 rows at destination with 2.365 ms to first row, 72 ms to end, start offset by 1.747 ms.    
         ->  Aggregate  (cost=163449.05..163449.06 rows=1 width=8)    
               Rows out:  Avg 1.0 rows x 33 workers.  Max 1 rows (seg0) with 0.002 ms to first row, 12 ms to end, start offset by 1.505 ms.    
               ->  Seq Scan on a  (cost=0.00..138450.04 rows=303019 width=0)    
                     Filter: c1 = 1    
                     Rows out:  Avg 303030.3 rows x 33 workers.  Max 303531 rows (seg23) with 5.279 ms to first row, 24 ms to end, start offset by 1.700 ms.    
 Slice statistics:    
   (slice0)    Executor memory: 373K bytes.    
   (slice1)    Executor memory: 302K bytes avg x 33 workers, 302K bytes max (seg0).    
 Statement statistics:    
   Memory used: 1280000K bytes    
 Optimizer status: legacy query optimizer    
 Total runtime: 75.788 ms    
(16 rows)    
相关文章
|
SQL 关系型数据库 数据库
PostgreSQL 设计优化case - 大宽表任意字段组合查询索引如何选择(btree, gin, rum) - (含单个索引列数超过32列的方法)
标签 PostgreSQL , adhoc查询 , 大宽表 , 任意字段组合查询 , 索引 , btree , gin , rum 背景 大宽表,任意字段组合查询,透视。是实时分析系统中的常见需求: 1、实时写入。
2466 0
|
2月前
|
存储 人工智能 Cloud Native
阿里云瑶池数据库训练营权益:《玩转Lindorm》学习资料开放下载!
阿里云瑶池数据库训练营权益:《玩转Lindorm》学习资料开放下载!
|
7月前
|
存储 SQL 机器学习/深度学习
VLDB论文解读|一文剖析阿里云Lindorm数据库在DB for AI领域的探索
论文主要针对大规模监控场景下海量时序数据的存储、访问、分析和管理带来的挑战,描述了阿里云多模数据库 Lindorm 带来的一站式解决方案。
|
7月前
|
存储 Java 数据挖掘
阿里云时序数据库简介和购买使用流程
阿里云时序数据库(Lindorm Time Series Database,简称TSDB)是阿里云原生多模数据库Lindorm中的核心组件,专门负责处理时序数据。它具有许多优势,包括高并发写入、高压缩比存储、实时时序指标聚合、统计、预测以及ML/AI计算等强大功能。 时序数据是指表示物理设备、系统、应用过程或行为随时间变化的数据,这类数据在物联网、工业物联网、基础运维系统等场景中有着广泛的应用。阿里云TSDB可以解决大规模时序数据的可靠写入问题,显著降低数据存储成本,并且能够实时灵活地完成业务数据的聚合分析。 TSDB针对不同应用场景,支持多元数据存储与索引,具有高效的写入性能和实时数据分析能
|
7月前
|
人工智能 自然语言处理 多模数据库
视野数科联合阿里云Lindorm多模数据库推动AIGC应用在金融领域落地
野数科与阿里云Lindorm多模数据库达成AIGC应用联合创新合作
|
9月前
|
SQL 消息中间件 监控
阿里云云原生多模数据库Lindorm简介和购买流程
Lindorm是面向物联网、互联网、车联网等设计和优化的云原生多模超融合数据库,支持宽表、时序、文本、对象、流、空间等多种数据的统一访问和融合处理,并兼容SQL、HBase/Cassandra/S3、TSDB、HDFS、Solr、Kafka等多种标准接口和无缝集成三方生态工具,是日志、监控、账单、广告、社交、出行、风控等场景首选数据库
|
11月前
|
Cloud Native 多模数据库
《阿里云产品手册2022-2023 版》——云原生多模数据库 Lindorm
《阿里云产品手册2022-2023 版》——云原生多模数据库 Lindorm
109 0
|
时序数据库
《阿里云时序数据库TSDB For InfluxDB?介绍》电子版地址
阿里云时序数据库TSDB For InfluxDB®介绍
138 0
《阿里云时序数据库TSDB For InfluxDB?介绍》电子版地址
|
存储 运维 Cloud Native
客户案例|国泰产险引入阿里云Lindorm数据库,实现存储成本降低75%
日前,国泰财产保险有限责任公司(以下简称“国泰产险”)通过引入阿里云Lindorm数据库,在历史保单分析场景下,查询性能获得约70%提升,同时通过Lindorm深度优化的ZSTD压缩算法,存储效率进一步提升30%,整体综合成本下降75%。
客户案例|国泰产险引入阿里云Lindorm数据库,实现存储成本降低75%
|
存储 传感器 监控
制造业全链数字化业务转型实践| 阿里云Lindorm与Intel、OSIsoft共建IT & OT超融合工业数据云
近日,阿里云Lindorm与Intel、OSIsoft推出了面向工业物联网信息经济(Infonomics)的IT & OT超融合工业数据云解决方案。方案通过云端打通阿里云、Intel的IT技术积累和OSIsoft的OT经验能力,实现对传统技术供需关系的超越,打造数据链和价值链混搭方式连接企业和供应商的开放、安全、共享的制造业数据云社区生态。
10415 0
制造业全链数字化业务转型实践| 阿里云Lindorm与Intel、OSIsoft共建IT & OT超融合工业数据云