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.pswp.cn/news/275363.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/275363.shtml
英文地址,請注明出處:http://en.pswp.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;可見王者榮耀帶來的影響有多大。新版王者榮耀隨著王者榮耀的優化和手機系統、硬…