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

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
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)    
目录
相关文章
|
5月前
|
机器学习/深度学习 分布式计算 大数据
MaxCompute产品使用合集之做一个宽表,字段有限制个数的吗
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
|
SQL 关系型数据库 数据库
PostgreSQL 设计优化case - 大宽表任意字段组合查询索引如何选择(btree, gin, rum) - (含单个索引列数超过32列的方法)
标签 PostgreSQL , adhoc查询 , 大宽表 , 任意字段组合查询 , 索引 , btree , gin , rum 背景 大宽表,任意字段组合查询,透视。是实时分析系统中的常见需求: 1、实时写入。
2676 0
|
5月前
|
存储 SQL 多模数据库
多模数据库Lindorm再升级:对接Dataphin,打通数据治理“最后一公里”
Lindorm通过与Dataphin的深度整合,进一步解决了数据集成和数据治理的问题,为企业提供更加高效和更具性价比的方案。
多模数据库Lindorm再升级:对接Dataphin,打通数据治理“最后一公里”
|
4月前
|
安全 数据管理
DataphinV4.1大升级:支持Lindorm开启高性价比数据治理,迎来“公共云半托管”云上自助新模式
DataphinV4.1大升级:支持Lindorm开启高性价比数据治理,迎来“公共云半托管”云上自助新模式
|
5月前
|
数据采集 安全 API
DataphinV4.1大升级: 支持Lindorm开启高性价比数据治理,迎来“公共云半托管”云上自助新模式
Dataphin 是阿里巴巴旗下的一个智能数据建设与治理平台,旨在帮助企业构建高效、可靠、安全的数据资产。在V4.1版本升级中,Dataphin 引入了Lindorm等多项新功能,并开启公共云半托管模式,优化代码搜索,为用户提供更加高效、灵活、安全的数据管理和运营环境,提升用户体验,促进企业数据资产的建设和价值挖掘。
1552 3
DataphinV4.1大升级: 支持Lindorm开启高性价比数据治理,迎来“公共云半托管”云上自助新模式
|
5月前
|
存储 DataWorks 安全
DataWorks产品使用合集之没有使用独享资源组,如何将Lindorm中的数据导出或迁移到其他数据存储服务
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
47 0
|
5月前
|
时序数据库
时序数据库工具grafana里的$timeFilter查询1个小时内的数据如何写查询条件
【6月更文挑战第24天】时序数据库工具grafana里的$timeFilter查询1个小时内的数据如何写查询条件
645 0
|
消息中间件 存储 弹性计算
lindorm多模间数据无缝流转
展现了Lindorm多模融合能力——用kafka API写入,无缝流转在各引擎内进行数据存储和计算的实验。
|
存储 NoSQL Oracle
「时序数据库」使用cassandra进行时间序列数据扫描
「时序数据库」使用cassandra进行时间序列数据扫描
|
SQL 存储 分布式计算
【时序数据库】时间序列数据和MongoDB第三部分-查询、分析和呈现时间序列数据
【时序数据库】时间序列数据和MongoDB第三部分-查询、分析和呈现时间序列数据