Greenplum 优化CASE - 对齐JOIN字段类型,使用数组代替字符串,降低字符串处理开销,列存降低扫描开销...

标签

PostgreSQL , 数组 , 字符串 , 字符串处理 , JOIN , where , 类型一致性


背景

Greenplum通常被用作OLAP,在一些用户使用过程中,可能因为数据结构设计,SQL问题等原因导致性能不佳,虽然通过增加节点可以解决问题,但是如果能优化的话,可以节约不少硬件资源。

例如

1、对齐JOIN字段类型。如果等值JOIN的字段类型不一致,无法使用HASH JOIN。

2、对齐where条件字段类型。同上,无法使用HASH JOIN,或者索引扫描。

3、使用数组代替字符串,降低字符串处理开销。如果字符串本身需要大量的格式化处理FILTER,那么使用数组的性能会好很多。

4、列存降低扫描开销,统计型的SQL由于涉及的字段有限,使用列存比行存储性能好很多。

例子

1、这个查询耗费230秒。

SELECT col4,count(DISTINCT c.col1) ptnum  from tbl1 a  INNER JOIN tbl2 b on b.col2=a.id  inner join tbl3 t2 on t2.ID <= (length(b.col3) - length(replace(b.col3,',',''))+1)   INNER JOIN tbl4 c   on replace(replace(Split_part(reverse(Split_part(reverse(Split_part(b.col3,',',cast(t2.id as int))),',',1)),':',1),'{',''),'"','') = c.id  INNER JOIN tbl5 s on a.col4=s.id  where replace(replace(reverse(Split_part(Split_part(reverse(Split_part(b.col3,',',cast(t2.id as int))),',',1),':',1)),'"',''),'}','') >'0'   and c.col1 not in ('xxxxxx')  GROUP BY col4;  

2、使用explain analyze分析瓶颈

3、问题:

3.1、JOIN类型不一致,导致未使用HASH JOIN。

3.2、有两个表JOIN时产生笛卡尔积来进行不等于的判断,数据量叠加后需要计算几十万亿次。

tbl2.col3字符串格式如下(需要计算几十万亿次)

{"2":"1","10":"1","13":"1","16":"1","21":"1","26":"1","28":"1","30":"1","32":"1","33":"1","34":"1","35":"1","36":"1","37":"1","39":"1","40":"1","99":"2","100":"2","113":"1","61":"1","63":"4","65":"2"}  

3.3、使用了行存储,查询时扫描的量较大,并且无法使用向量计算。

优化

1、使用列存代替行存(除nestloop的内表tbl3,继续使用索引FILTER)

create table tmp_tbl1 (like tbl1) WITH (APPENDONLY=true, ORIENTATION=column);  
insert into tmp_tbl1 select * from tbl1;  
create table tmp_tbl4 (like tbl4) WITH (APPENDONLY=true, ORIENTATION=column);  
insert into tmp_tbl4 select * from tbl4;  
create table tmp_tbl5 ( like tbl5) WITH (APPENDONLY=true, ORIENTATION=column);  
insert into tmp_tbl5 select * from tbl5;  
create table tmp_tbl2 (like tbl2) WITH (APPENDONLY=true, ORIENTATION=column) distributed by (col2);  
insert into tmp_tbl2 select * from tbl2;  

2、使用array代替text

alter table tmp_tbl2 alter column col3 type text[] using (case col3 when '[]' then '{}' else replace(col3,'"','') end)::text[];  

修改后的类型、内容如下

digoal=> select col3 from tmp_tbl2  limit 2;  col3                                                       
------------------------------------------------------------------------------------------------------------------------  {63:1,65:1,70:1,71:1,73:1,75:1,77:1,45:3,78:1,54:2,44:1,80:1,36:1,84:1,96:2}  {2:2,10:1,13:1,16:1,30:1,107:1,26:1,28:1,32:1,33:1,34:1,35:1,36:1,37:1,39:1,99:2,100:2,113:1,40:1,57:1,63:2,64:1,65:4}  
(2 rows)  

3、join 字段保持一致

alter table tmp_tbl2 alter column col2 type int8;  

4、将原来的查询SQL修改成如下(字符串处理变成了数组)

(本例也可以使用二维数组,完全规避字符串处理。)

SELECT col4,count(DISTINCT c.col1) ptnum  from tmp_tbl1 a  INNER JOIN tmp_tbl2 b on b.col2=a.id  inner join tbl3 t2 on t2.ID <= array_length(col3,1)  -- 更改  INNER JOIN tmp_tbl4 c   on split_part(b.col3[cast(t2.id as int)], ':', 1) = c.id   INNER JOIN tmp_tbl5 s on a.col4=s.id  where split_part(b.col3[cast(t2.id as int)], ':', 2) > '0'   and c.col1 not in ('xxxxxx')  GROUP BY col4;   

执行计划

                                                                                           QUERY PLAN                                                                                              
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------  Gather Motion 32:1  (slice7; segments: 32)  (cost=543258065.87..543259314.50 rows=41621 width=12)  ->  GroupAggregate  (cost=543258065.87..543259314.50 rows=1301 width=12)  Group By: a.col4  ->  Sort  (cost=543258065.87..543258169.93 rows=1301 width=12)  Sort Key: a.col4  ->  Redistribute Motion 32:32  (slice6; segments: 32)  (cost=542355803.38..543254872.50 rows=1301 width=12)  Hash Key: a.col4  ->  GroupAggregate  (cost=542355803.38..543254040.08 rows=1301 width=12)  Group By: a.col4  ->  Sort  (cost=542355803.38..542655042.19 rows=3740486 width=11)  Sort Key: a.col4  ->  Redistribute Motion 32:32  (slice5; segments: 32)  (cost=6247.23..518770960.13 rows=3740486 width=11)  Hash Key: c.col1  ->  Hash Join  (cost=6247.23..516377049.63 rows=3740486 width=11)  Hash Cond: split_part(b.col3[t2.id::integer], ':'::text, 1) = c.id::text  ->  Nested Loop  (cost=5494.14..476568597.41 rows=3852199 width=491)  Join Filter: split_part(b.col3[t2.id::integer], ':'::text, 2) > '0'::text  ->  Broadcast Motion 32:32  (slice3; segments: 32)  (cost=5494.14..115247.73 rows=277289 width=483)  ->  Hash Join  (cost=5494.14..23742.36 rows=8666 width=483)  Hash Cond: b.col2 = a.id  ->  Seq Scan on tmp_tbl2 b  (cost=0.00..14088.89 rows=8666 width=487)  ->  Hash  (cost=4973.86..4973.86 rows=1301 width=12)  ->  Redistribute Motion 32:32  (slice2; segments: 32)  (cost=2280.93..4973.86 rows=1301 width=12)  Hash Key: a.id  ->  Hash Join  (cost=2280.93..4141.42 rows=1301 width=12)  Hash Cond: s.id = a.col4  ->  Append-only Columnar Scan on tmp_tbl5 s  (cost=0.00..1220.97 rows=1491 width=4)  ->  Hash  (cost=1760.66..1760.66 rows=1301 width=12)  ->  Redistribute Motion 32:32  (slice1; segments: 32)  (cost=0.00..1760.66 rows=1301 width=12)  Hash Key: a.col4  ->  Append-only Columnar Scan on tmp_tbl1 a  (cost=0.00..928.22 rows=1301 width=12)  ->  Index Scan using idx_codeid on tbl3 t2  (cost=0.00..23.69 rows=42 width=8)  Index Cond: t2.id <= array_length(b.col3, 1)  ->  Hash  (cost=364.69..364.69 rows=972 width=11)  ->  Broadcast Motion 32:32  (slice4; segments: 32)  (cost=0.00..364.69 rows=972 width=11)  ->  Append-only Columnar Scan on tmp_tbl4 c  (cost=0.00..44.26 rows=31 width=11)  Filter: col1 <> 'xxxxxx'::text  Settings:  effective_cache_size=8GB; enable_nestloop=off; gp_statistics_use_fkeys=on  Optimizer status: legacy query optimizer  
(39 rows)  

性能提升

原来SQL响应时间: 230秒

修改后SQL响应时间: < 16秒

小结

瓶颈分析

1、JOIN时不等条件,必须使用笛卡尔的方式逐一判断,所以如果FILTER条件很耗时(CPU),那么性能肯定好不到哪去。

2、原来大量的reverse, split, replace字符串计算,很耗时。刚好落在笛卡尔上,计算数十万亿次。

3、JOIN字段类型不一致。未使用HASH JOIN。

4、分析SQL,未使用列存储。

优化手段

1、array 代替字符串。

2、改写SQL

3、对齐JOIN类型。

4、使用列存储。

5、保留的NESTLOOP JOIN,内表保持行存储,使用索引扫描。(如果是小表,可以使用物化扫描,更快)

6、analyze table;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/275363.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

杭州 3~5年 前端面经,高频面试题总结

大家好&#xff0c;我是若川。假期归来&#xff0c;国庆期间没有更文&#xff0c;不用想每天发什么文章&#xff0c;不用担心阅读量&#xff0c;其实感觉挺好。最近组织了源码共读活动《1个月&#xff0c;200人&#xff0c;一起读了4周源码》&#xff0c;已经有超100人提交了笔…

职称以考代评学院考计算机吗,软考与职称的关系,软考是以考代评,不用另外再去评审...

Hokfung(cnitpm.com) 15:16:45软考与职称关系&#xff1a;通过了软考,我们所获得的只是一种资格,是否聘任相应的职称,完全取决于各单位的实际情况&#xff0c;国家有关部门并没有直接的规定。事实上,通过评审方法(也就是常说的"评职称”) 得到的也只是一个资格,单位既可以…

figma下载_我关于Figma文件封面的故事

figma下载It was 8:40 AM in the morning. I woke up from the bed as my subconscious memory reminded me of the team meeting at 9 AM to discuss what I am working on.早上8:40。 我从床上醒来&#xff0c;因为我的潜意识使我想起了上午9点的团队会议&#xff0c;讨论我的…

图解选择排序与插入排序

上一篇详述了冒泡排序及其优化&#xff0c;有兴趣的可以看看&#xff1a; 如何优化冒泡排序&#xff1f; 一、选择排序&#xff08;SelectionSort&#xff09; 算法思想&#xff1a;首先在未排序序列中找到最小&#xff08;大&#xff09;元素&#xff0c;存放到排序序列的起始…

2011年上半年网页游戏开测数据报告发布

网页游戏上半年统计数据显示&#xff0c;2011年上半年&#xff0c;网页游戏开测信息总数为304款&#xff0c;排除重复开测信息&#xff0c;在2011年1月1日至6月30日这段期间&#xff0c;共收录开测&#xff08;含首次开测或更名的&#xff09;的数据为129条。 新公布的产品&…

计算机python程序设计导论,程序设计导论:Python计算与应用开发实践(原书第2版)...

程序设计导论&#xff1a;Python计算与应用开发实践(原书第2版)语音编辑锁定讨论上传视频《程序设计导论&#xff1a;Python计算与应用开发实践(原书第2版)》是2018年机械工业出版社出版的图书&#xff0c;作者是[美] 卢博米尔佩尔科维奇(Ljubomir Perkovic)。书 名程序设计…

vue-cli 将被 create-vue 替代?初始化基于 vite 的 vue3 项目为何如此简单?

大家好&#xff0c;我是若川。最近组织了源码共读活动《1个月&#xff0c;200人&#xff0c;一起读了4周源码》&#xff0c;已经有超50人提交了笔记&#xff0c;群里已经有超1500人&#xff0c;感兴趣的可以点此链接扫码加我微信 ruochuan12create-vue公开了&#xff0c;可以使…

lynda ux_如何进入UX领域

lynda uxI often get asked “What is the right path I should take to get into UX?” and more often than not, I do not have a direct answer. I usually ask a lot of questions about their background, before assessing their current skills with the things they …

php字符串学习笔记

在这里记录下今天的所得首先对字符串处理进行分类今天主要记录有以下字符串的格式化字符串的连接与分割字符串的比较使用字符串函数匹配和替换子字符串使用正则表达式1.字符串的格式化<?php //整理字符串的第一步是清理字符串中的多余的空格 // trim() ltrim() rtrim() // …

This is a Blog Test

Blog Test Hello, everyone! I am going to write blog to record the knowledge about the computer technology involved when I study. Please feel free to comment on any mistakes. Thank you! print("Hello")转载于:https://blog.51cto.com/12370958/2379111

可以测试体育跑步的软件,某高校现跑步打卡神器 能检测出是在走还是跑

[摘要]近日&#xff0c;一批高大上的“阳光跑步神器”在东莞一所高校火了&#xff01;之所以称之“神器”&#xff0c;是由于这批机器能检测到你在走路还是在跑步&#xff0c;如果走路数据将中断。消息一出&#xff0c;学生们有赞成&#xff0c;也有大呼“吃不消”。东莞某高校…

一道很熟悉的前端面试题,你怎么答?

大家好&#xff0c;我是若川。最近这几年&#xff0c;云计算的普及和 HTML5 技术的快速发展&#xff0c;越来越多的应用转向了浏览器 / 服务器&#xff08;B/S&#xff09;架构&#xff0c;这种改变让浏览器的重要性与日俱增&#xff0c;视频、音频、游戏几大核心场景也都在逐渐…

:寻找指定和的整数对_寻找时间:如何增加设计的时间

:寻找指定和的整数对Good design derives from good thinking. And good thinking is highly correlated to how much time you spend. In every place I’ve been though, every designer seems to be thirsty for more time to design. Why does this happen, to a point whe…

JavaScript命名空间namespace的实现方法

网上有很多了&#xff0c;这里给出一个&#xff0c;其实思路就是A{}; A.b{};其实b是A的一个属性。只是做了一些封装&#xff0c;最后的效果是可以直接定义多个namespace&#xff1a; 1: My.namespace("Company", "Company.Feed", "Company.Feed.Mess…

通过MySQL存储原理来分析排序和锁

先抛出几个问题1.为什么不建议使用订单号作为主键?2.为什么要在需要排序的字段上加索引?3.for update 的记录不存在会导致锁住全表?4.redolog 和 binlog 有什么区别?5.MySQL 如何回滚一条 sql ?6.char(50) 和 varchar(50) 效果是一样的么?索引知识回顾对于 MySQL 数据库而…

1600k 打印头测试软件,巧修LQ-1600K打印机打印头

LQ-1600K 24针中英文打印机&#xff0c;由于其打印速度快、输出的文字漂亮、软件兼容性好等优点&#xff0c;在国内得到极为广泛的应用。但该机的打印头及打印针驱动电路故障率较高&#xff0c;一旦出现此类故障&#xff0c;打印效果将大打折扣。本人在长期维修工作中&#xff…

linkedin爬虫_重新设计Linkedin的指导功能-用户体验案例研究

linkedin爬虫为什么选择导师 Linkedin平台&#xff1f; (Why mentorship Linkedin platform?) As a recent graduate, I went on Linkedin to seek career advice and mentorship. This idea came so naturally that I was quite surprised by the absence of a complete fea…

POJ 1797 Heavy Transportation 解题报告

分类&#xff1a;图论&#xff0c;生成树&#xff0c;最短路&#xff0c;并查集作者&#xff1a;ACShiryu时间&#xff1a;2011-7-28地址&#xff1a;ACShiryus BlogHeavy TransportationTime Limit: 3000MSMemory Limit: 30000KTotal Submissions: 11929Accepted: 3171Descrip…

曾以为只能拿8K,22届学弟字节校招心路历程

大家好&#xff0c;我是若川。最近组织了源码共读活动《1个月&#xff0c;200人&#xff0c;一起读了4周源码》&#xff0c;已经有超50人提交了笔记&#xff0c;群里已经有超1500人&#xff0c;感兴趣的可以点此链接扫码加我微信 ruochuan12这篇文章记录了江西师大学弟进入字节…

王者荣耀cpu测试软件,你的手机能否玩王者荣耀,主流处理器新版王者荣耀测试...

说道国民级手游&#xff0c;目前来看那绝对是王者荣耀和刺激战场&#xff0c;之前的话那可是王者荣耀的天下&#xff0c;甚至许多手机厂商在发布新手机的时候会专门公布王者荣耀的帧率&#xff0c;可见王者荣耀带来的影响有多大。新版王者荣耀随着王者荣耀的优化和手机系统、硬…