實時數倉入門訓練營:Hologres性能調優實踐


簡介: 《實時數倉入門訓練營》由阿里雲研究員王峰、阿里雲資深技術專家金曉軍、阿里雲高級產品專家劉一鳴等實時計算 Flink 版和 Hologres 的多名技術/產品一線專家齊上陣,合力搭建此次訓練營的課程體系,精心打磨課程內容,直擊當下同學們所遇到的痛點問題。由淺入深全方位解析實時數倉的架構、場景、以及實操應用,7 門精品課程幫助你 5 天時間從小白成長為大牛!

本文整理自直播《Hologres性能調優實踐-清芬》
視頻鏈接:https://developer.aliyun.com/learning/course/807/detail/13889

內容簡要:

一、Hologres建表最佳實踐
二、Hologres性能問題分析與優化

一、Hologres建表最佳實踐

(一)建表優化的必要性

為什么Hologres建表優化非常重要?
image.png
首先,對於整個的查詢性能以及寫入性能來講,一個好的建表跟一個比較差的建表,性能上面有非常大的區別。
其次,建表優化需要盡早做,是因為Hologres在改 DDL的同時,有可能需要用戶重復進行一些數據導入,這種重復的工作使得我們希望盡早完成建表優化。
最后,一個好的建表對於用戶的數據存儲成本也有一定的幫助。如果建表做得不恰當,可能導致建一些不必要的Index,然后導致數據多了一些冗余的存儲,從而提升了成本。
因此,建表優化是非常重要的,這也是把它作為本文第一部分的原因。

(二)業務建模是性能優化的前提

image.png
說完建表的重要性之后,我們再看建表優化之前要去做整個業務建模的優化。在考慮使用Hologres的同時,我們要知道通過Hologres能夠解決什么樣的業務問題,以及通過什么樣的方式解決。
Hologres本身是一個HASP產品,在使用Hologres的同時就需要跟業務場景結合,我們要知道這個場景到底是分析場景還是在線服務場景。如果是一個分析型,就用Hologres的列存比較友好,如果是一個在線服務型場景,就用行存比較友好,這些是跟業務場景相關的。
第二個是要能夠結合Hologres本身的產品優勢。Hologres是一個在線服務以及交互式分析的產品,它並不適合ETL以及海量數據拖取的場景。因此,在把業務往Hologres上面搬的時候,不能搬所有的場景,否則可能導致Hologres做一些不太適合本身的事情,信任就會不太好。
第三個是需要做一些取舍。為了達到預期的性能,可能需要做一些類似預計算或者數據加工的提前操作,減少后續計算復雜度,加快計算速度。

以上這些都跟預先數據建模以及整個業務期望息息相關。

(三)存儲方式的選擇

做完以上准備工作之后,我們需要進行Hologres管理存儲方式的選擇。
Hologres本身支持兩種存儲方式,分別是行存和列存。
image.png
行存主要的應用場景是對主鍵進行高QPS查詢,並且當我們表比較寬的時候,一次查詢會讀取大量列,這種場景適用Hologres是非常適合的。
除此之外, Blink的維表查詢必須是用行存,因為一般情況下Blink的維表是高QPS、基於Key的查詢,列存沒有辦法扛住這么高的壓力。
列存適用於復雜的交互式分析查詢,比如一個查詢里面,它有關聯、聚合等等各種各樣的復雜計算。同時它覆蓋的場景非常多,包括過濾、聚合等,列存是比較通用的存儲方式。
行存主要適用於在線服務類的場景,列存主要適用於分析型的場景,這是兩個存儲方式的選擇區別。

(四)優化Shard數

Shard_count: Shard實現了物理分表的效果,多個Shard並行服務查詢。
增加Shard可以增加查詢的分布式並行度,更多Shard不一定查詢更快,也會帶來並發查詢的調度開銷。

說完存儲方式,接下來我們看Shard數。
Hologres在存儲的時候,是把物理表分成一個個Shard存儲,每個表會按照一定的分布方式分布到所有的物理節點上面,然后每個Shard可以去並發進行查詢,Shard數越多,相當於整個查詢的並發度越高。但是Shard數也不是越多越好,因為它本身有一些額外的開銷,所以我們需要根據整個查表的數據量以及查詢復雜度來設計每個表的Shard數。
image.png
在集群擴容的時候,比如我們原本是128 Core的實例,擴容到256 Core之后,我們需要對整個Shard數進行一定的調整,這樣才能享受擴容帶來的性能提升。
因為我們整個並發度是在Shard數上面,假如實例擴容了,但是Shard數沒變,那么相當於整個計算的並發度沒變,這種情況會導致雖然擴容了,但是查詢性能沒有提升。

一般情況下,我們會建議用戶將Shard數設置成跟實例規格差不多的數量,比如一個64 Core的,Shard數設成40或64這種比較貼近於實例規格的數量。當規格往上漲之后,我們希望Shard數也能往上漲,從而提高整個查詢的並發度。

(五)優化Distribution Key

然后說完Shard數之后,我們再看一下Hologres里面非常重要的Distribution Key,它主要是用來決定數據如何分到每個Shard上面。

Distribution_key:均衡地分發數據到多個Shard中,令查詢負載更均衡,查詢時直接定位到對應Shard。
如果創建了Primary Key索引(用於數據更新),默認為distribution_key, Distribution_key如果為空,默認是Random,Distribution_key需是Primary Key的子集。

一個好的Distribution Key設計,首先要求用戶的數據在Distribution Key上划分比較均勻。
比如用戶ID或者是商品寶貝ID,一般情況下Key只有一個,所以它是非常均勻的,是用來作為Distribution Key非常好的例子。但是像年齡或者性別這種就不太適合作為Distribution Key,因為它可能會使大量的數據Shuffle到一個節點上,導致整個數據的分布不是很均勻。
Distribution Key主要的作用是減少關聯查詢、聚合運算里數據的Shuffle。
如果用戶沒有設置Distribution Key,那么我們默認是Random,因為我們會保證用戶的數據能夠盡可能均勻地分布到所有Shard上面。

接下來我們看一下Distribution Key主要的作用。
image.png
在Hologres里面我們會有不同的表,放到不同的TableGroup里面,對於Shard數相同的表,都會放到一個TG下面。
假設兩個表做關聯,如果都按照關聯的Key去設計Distribution Key,那么這兩個表的關聯就可以做一個Local Join,如上圖左邊所示。所有的數據不需要做額外的Shuffle,每個表在每個Shard上面,做完關聯之后直接產生結果。
假如數據量增大,之后可能需要擴容,我們希望在這個TG下面所有表都會進行擴容,這樣能保證數據分布的一致性,維持住整個Local Join,而不會因為擴容導致做不了Local Join。
Local Join相比於非Local Join,性能差別非常大,通常會有一個數量級左右的差異。
跟Local Join最相關的就是Distribution Key的設計,如果Distribution key設計不合理時,在Join時,可能引起大量的Data Shuffle,影響效率。
image.png
如上圖所示,假設表A跟表B要做一個關聯,如果不是Distribution Key的場景,那么我們就需要把表A的數據跟B的數據都按照它的Join Key做Shuffle, Shuffle會帶來非常高昂的成本,同時影響整個查詢的效率。
所以通常情況下,對於需要連接的表,可以把Join關系設為distribution key,實現Table在同一個Shard內Local Join。

(六)優化分區表

分區表:也是物理表,具備一樣的Shard能力,但多了一個根據分區鍵進行Table Pruning的能力。
image.png

如上圖所示,假設查詢的過濾條件只命中了部分的分區,那么剩下的分區表就不需要進行掃描,這能夠大大節約整個查詢的IO,加快查詢速度。
通常情況下,分區的Key是靜態的,並且數量不會太多,最適合做分區Key的是日期。例如有的業務方是一天一個分區,或者按小時分區,那么查詢的時候也會按照某一段時間來過濾數據。
通過分區表,當用戶的查詢條件包含時間過濾時,就可以把不必要的分區過濾掉,對查詢性能有很大的的提升。
通常將日期列等基數低(小於一萬)的字段用於做分區字段,如果分區表過多, 而查詢時不帶有分區過濾條件,性能會下降。

(七)優化Segment Key

Shard是一個邏輯數據單位,物理上是一組文件(分發到同一個Shard的多個表,以及對應的索引)。
image.png

Segment Key主要是作用於列存。
在列存上面,文件是存成一個個Segment,當查詢到了某一個Shard上,因為Shard內部有一堆的文件,我們要去找哪些文件會命中這個查詢,需要進行掃描,Segment Key是用來跳過不需要查找的文件。
假設Segment設成了一個時間,數據按照時間寫入,比如10點到11點是一個文件,11點到12點是一個文件,12點到13點是一個文件。當我們要查詢12:15~12:35區間范圍的數據,對於這種情況,通過Segment Key就能快速找到12點到13點這個文件命中查詢,所以只要打開這一個文件就可以了。通過這種方式就可以快速跳過不必要的文件掃描,減少IO,讓整個查詢更快。
上圖主要是介紹了整個數據的寫入流程,幫助大家理解Segment Key到底是什么樣的。
剛才提到當數據寫入Hologres,會寫到內存表里面,內存寫滿了,異步Flush到文件,Append Only寫入,寫入效率最高。因為寫入時為了性能,沒有全局排序和單文件更新,文件之間存在Overlap。
這是什么意思?

Segment_key用於文件塊的邊界划分,查詢時基於Segment_key可以快速定位數據所在文件塊, Segment_key多列時,按照左對齊。

如上文提到的例子,11點到12點在一個文件是比較理想的情況,實際情況可能是11點到12點在一個文件,11:30~12:30是在第二個文件里面,12:30 ~13:00又是一個文件,文件之間可能存在重疊。查詢可能會命中多個文件,這種場景可能就會導致需要打開多個文件。
所以在設計Segment Key的時候,盡可能不要有Overlap,盡可能順序地遞增。如果數據寫入非常無序,比如寫進來的數據,先是123,然后678,然后456,這種亂序的寫入就會導致Segment Key可能在不同的文件內部有重復的數據,使得Segment Key完全沒有起到查詢過濾的作用。
因此,設計Segment Key最關鍵的一點就是盡可能單調,並且沒有Overlap,這樣才可以讓我們能夠盡可能跳過這種不必要的數據掃描。
Segment Key的設計主要是用在Blink的實時寫入場景,並且把Key設成時間字段,因為它數據實時寫入的時間是遞增的,並且每個值不會有很大的 Overlap,比較適合用Segment Key。
除此之外,其他的場景不太建議用戶自己設Segment Key。

(八)優化ClusteringKey

Clustering_key,文件內聚簇布局,表示排序信息,和MySQL 的聚簇索引不同,Hologres用來布局數據,不是布局索引,因此修改Clustering需要重新數據導入,且只有一個 Clustering_key,排序操作在內存中完成生成SST。
image.png

上圖為一個例子,上圖的左邊是一個完全無序的情況,如果按照Date作為ClusteringKey,那么會變成右上角的圖。按照Date做完排序之后,當進行Date查詢,比如Date大於1/1,小於1/3的數據,可以快速查到對應的時間段。
假設沒有做這個Index,我們就需要把所有數據都掃一遍,這就是通過ClusteringKey加速查詢的原理。
假設按照Class做排序,如果將Class和Date作為ClusteringKey,那么會先按照Class做排序,然后再按照Date排序,如上圖右下方所示。對於這種場景,ClusteringKey的設計是按照最左匹配的原則,就是當遇到用戶的查詢條件,也按照最左匹配的原則來匹配。
例如,查詢的Key是Class,那么能夠命中ClusteringKey,如果查詢條件是Class跟Date,也能夠命中ClusteringKey,但如果查詢條件只有Date,則無法命中ClusteringKey。遵循的最左匹配相當於,從左往右的條件中,無論用戶的查詢條件有幾個,最左邊的條件必須匹配上才可以。
ClusteringKey主要的作用是能夠加速查詢的過濾,Range查詢的過濾以及點查的過濾。ClusteringKey的缺點是每個表最多只能有一個ClusteringKey,只能有一種排序方式。

(九)優化字典編碼

字典編碼對於字符串類型可以有效壓縮,特別是基數小的列。編碼值可以加快比較操作,對於Group By,Filter有好處,Holo在0.9之后自動設置。
image.png
上圖為字典編碼的一個例子。
如上圖左邊所示,有Card No和男女性別Gender。因為男女性別只有兩個值,所以非常適合於用字典編碼,假如把性別編碼成0跟1,就變成了圖中間的方式。
當進行數據查詢的時候,需要對過濾條件的編碼,比如想查所有男性的Card No,過濾條件就變成了Gender 0,通過這種方式進行數字查詢。
但是字典編碼有一個缺點,就是對於基數列比較大的場景,它的開銷非常高。
因為我們對數據先進行編碼,編碼的過程中,假如數據一共是100萬行,其中有99萬行不一樣的值,這會導致我們有99萬個Encoded值,這種情況會造成整個編碼跟查詢的耗損非常高,這種情況就不太適合做字典編碼。
在Hologres0.9之后,我們支持自動設置字典編碼,用戶無需自己去配置字典編碼。

(十)優化位圖索引

位圖索引,對於等值過濾場景有明顯的優化效果,多個等值過濾條件,通過向量比較計算。

位圖索引相當於把每列的數據通過位圖來標識它是否存在。
image.png
如上圖所示,我們將左邊表中學生的性別、班級進行位圖編碼,就得到了右邊的圖,通過這些位圖信息我們可以進行快速過濾。
例如,我們要查所有男性學生,可以通過“1 0”進行過濾,得到右圖中PK值為1、2、5、6這四行符合查詢條件的數據。假設要過濾出三班的同學,那么我們再構建一個位圖“0 0 1”,再跟班級的數據做一個過濾,就能得到PK值為2和6的信息。
可以看到,位圖索引主要的應用場景是在點查,比如查詢條件是男性並且年齡等於32歲,這種場景也是非常適合用位圖進行查詢加速。
同樣的,位圖索引也有個問題,就是基數過多的列,在位圖索引編碼時,會形成稀疏數組(列很多,值很少),對查詢性能改善影響小。

(十一)物理拓撲

上文闡述了幾個索引以及整個存儲方式,下面看一下如何區別它們,以及整個用戶視角看起來它大概是什么樣的抽象。
image.png
如上所示,用戶寫了一個SQL之后,首先會按照用戶分區鍵路由到對應要找的表上面,找對邏輯對象Table。
第二步通過Distribution Key找到對應Shard。
第三步是Segment Key,找到Shard之后要找對應Shard上面的文件,因為實際數據是存儲成一個個文件,我們通過Segment Key找到想要打開的文件。
第四步是在文件內部,數據是否有序,這是通過Clustering Key來查找的,Clustering Key幫助我們找對實際文件區間。
第五步是Bitmap。因為Hologres把數據按照一個個Batch存儲,在一個Batch里面,我們需要通過Bitmap快速定位到某一行,否則需要把某一個區間范圍內所有的數據掃一遍。
圖中從上往下不同的過程,越來越到文件內部,越往上是越大的范圍。

二、Hologres性能問題分析與優化

(一)性能白皮書

用戶問得最多的問題是Hologres的性能如何,我們有一個大概的性能估量。
image.png
使用Hologres時,實時寫入單Core的QPS是5000,對於離線寫入的場景,比如Max Computer寫入到Hologres,通常情況下單Core的QPS能到5W。對於OLAP查詢,單Core處理200萬數據量。對於點查場景,單Core QPS在1W左右。
用戶可以根據以上信息來評估自己的查詢以及業務場景需要用多少資源。

(二)實時寫入與點查

對於不同的應用場景,我們優化手段是不太一樣。
image.png
對於實時寫入與點查的場景,首先要檢查建表是否合適。對於高QPS寫入以及點查來說,我們希望Distribution Key和查詢條件一致。因為Distribution Key用來找到對應的Shard,在寫入的QPS很高的情況下,假如過濾條件與分布Key一致,我們就可以快速路由到某一個Shard上面,這個查詢就不需要發到所有Shard上,對這種場景有很大的性能提升,所以要求Distribution Key和查詢條件一致。

第二個是我們的表最好是行存表,因為行存表對實時寫入以及點查在性能上非常友好。

第三個場景是假設不是行存表而是列存表,我們希望Pk、Clustering Key和查詢條件一致,這樣才能用上Clustering Index的能力。

除了建表優化以外,還需要優化查詢寫入代碼。因為如果寫Hologres的代碼設計得不合理,會帶來非常高昂的額外成本。可能用戶會發現QPS好像已經上不去了,但其實Hologres內部CPU使用率非常低,這是因為用戶自己的寫入代碼不是特別高效。

對於這樣的問題,首先我們希望用戶盡可能通過Preparestmt的方式,它主要的好處是能夠節約整個執行計划的開銷。提交一個SQL之后,一般會把 SQL進行編譯解析,然后生成一個執行計划,最后提交到執行引擎來執行這樣的一個過程。當數據重復執行SQL的時候,使用Preparestmt就可以不用再去做生成、執行計划、解析的過程,成本大大減少,查詢和寫入的QPS會更高。

第二點是我們希望用戶寫入的數據盡可能湊批。比如說我們經常會碰到一些用戶,他會先寫insert into values1和insert into values2,再寫insert into values2和insert into values3,然后不停地發這種小的SQL進行數據插入,這會帶來非常高昂的數據RPC成本,同時整個QPS也上不去。
我們通過湊批可以讓寫入性能會高很多,比如通過insert into values的方式,一個values里面就包含了1000個值或者1萬個值,這1萬個值的寫入只要一次數據傳輸就可以了。相比於之前的方式,性能上可能存在1萬倍的差異。

第三塊是整個Holo Client的使用,有的用戶可能不太清楚如何優化代碼,或者不能湊好批,Holo Client可以幫助用戶解決這些問題。

相比於傳統的JDBC Client,Holo Client幫用戶做了各種各樣異步化的封裝以及湊批的邏輯,並且它沒有SQL引擎的額外開銷,不需要進行一些SQL解析的操作,所以它的寫入跟查詢性能相比於使用JDBC的方式會好非常多。
Holo Client也是Blink Client寫入的內置插件,所以它相比用戶自己的工具,寫入性能會更好。
還有一點是我們連接的時候盡可能使用VPC域名進行數據的寫入跟查詢。
因為直接用公網的話,網絡之間的RT比較高。如果用VPC網絡,因為是在同一個網站內,機器之間的RT比較低,能夠減少整個網絡上面的開銷,在很多應用場景下,它的影響非常大,也非常重要。

(二)離線寫入與查詢常見問題

接下來我們看一下離線寫入與查詢常見的問題。
為什么把離線寫入跟查詢放在一起?這是因為離線寫入跟查詢是一樣的原理,離線寫入也是通過跑一個Query,跑Query方式的問題都是差不多的。
image.png
首先是統計信息缺失。
Hologres本身是一個分布式引擎,它要把用戶寫的SQL運行在分布式引擎上,因此需要去優化器生成一個執行計划,優化器需要統計信息來幫助它生成一個比較好的執行計划。當遇到用戶統計信息缺失,優化器相當於喪失了輸入,無法生成執行計划,這是我們在線上遇到最大也是最多的一個問題。
第二個很大的問題是建表不優,當遇到建表跟查詢不一致的情況,就會導致整個查詢的性能非常差。
除此之外,Hologres是一個自研的引擎,但是為了兼容Postgres的開源生態,所以會有一個聯邦查詢的機制,使得用戶能在Postgres運行的Query也能在Hologres運行,但是它會帶來一些額外的性能損失。

(三)查看執行計划

執行計划的好壞對於查詢性能影響非常大。Hologres的查詢優化器會根據 Cost選擇執行耗時最低的查詢計划來執行用戶的查詢,不過難免會出現一些查詢計划不優的情況。用戶可以通過Explain命令來查詢執行計划,執行計划中一般包含以下算子:
1.數據掃描算子:Seq Scan、Table Scan及Index Scan等。
主要是用來進行數據訪問,Seq Scan、Table Scan及Index Scan分別對應順序掃描,表掃描以及基於Index的掃描。
2.連接算子:Hash Join及Nested Loop。
Hash Join的意思是兩個表做關聯的時候,會先把一個表做成Hash Table,另外一個表通過Hash Table的Lookup進行關聯查詢。
Nested Loop會把兩個表做成兩個For循環,在外表就是一個表 For循環遍歷所有的數據,另外一個表也是For循環,這就是Hash Join與Nested Loop的區別。
3.聚合算子:Hash Aggregate及Streaming Aggregate。
基於Hash查找的AGG實現及基於排序的AGG實現。
4.數據移動算子:Redistribute Motion、Broadcast Motion及Gather Motion等。
Hologres是一個分布式的引擎,所以難免會碰到數據Shuffle的情況。Redistribute Motion主要是做數據的Shuffle,Broadcast Motion是做數據廣播,Gather Motion是把數據拉到一起,這些數據移動算子主要是用來解決分布式數據的問題。
5.其他算子:Hash、Sort、Limit及Append等。

(四)統計信息缺失

我們在看Query性能的時候經常會碰到幾個問題,其中一個是統計信息缺失,我們如何知道統計信息是否缺失?
image.png
上方是一個explain查詢的例子。當Hologres沒有統計信息,行數的默認值是1000。這里我們可以看到,當前tmp和tmp1兩個表的行數都是1000,表明這兩個表目前都拿不到統計信息。
沒有統計信息容易出現的問題:

  • 跑查詢OOM
  • 寫入性能差

(五)更新統計信息

那么我們怎么解決沒有統計信息的問題?
通過Analyze命令,用戶可以更新統計信息。
image.png
還是之前的例子,通過analyze tmp;和analyze tmp1,可以看到這兩個表就有統計信息了,如上方所示。
從上方可以看到,tmp1有1000萬行數據,它1000萬數據Join 1000行數據,此時我們發現,這個表雖然做了個Hash Join,但它的Join順序是不對的。因為在這之前tmp的數據量非常小,而temp1數據量非常大,會導致把tmp1放到了Hash Table這一側,然后Hash Table非常大,導致整個Join性能非常差。
通過Analyze之后,可以把Join的順序調過來,把小的表tmp放在被Hash這一側,把大的表tmp1放在關聯的那一側,形成一個比較好的查詢計划,查詢性能相比之前也有一個比較大的提升。

(六)選擇合適的分布列

我們需要選擇合適的分布列,也就是本文前面提到的做Local Join的情況。如果用戶不設置分布列,在進行關聯查詢時,Hologres需要將2個表的數據根據join key shuffle到一起,保證數據的正確性。如果shuffle的數據量很大,會造成很高的查詢延遲。
我們如何判斷有沒有做Local Join?
image.png
在上方示例中我們可以看到,通過explain查看執行計划,Redistribute Motion表示Shuffle算子,tmp和tmp1兩個表在做關聯之前都通過Join條件作了Shuffle,這說明整個關聯不是一個Local Join。
解決方法是把關聯Key設置成Distribution Key。
image.png
具體做法是重新建表,關聯Key設成a跟b,此時我們再去查看執行計划,就沒有Redistribute Motion了,這個關聯就是一個Local Join。
image.png
通過這種方式就可以讓整個關聯從非Local Join變成了Local Join,性能相對之前也有一個比較大的改善。

(七)判斷是否用上Clustering Key

接下來看一下怎么通過執行計划來看我們之前的那些建表的Index,判斷是否用上Clustering Key。
image.png
如上方所示,假如我們寫了個查詢:
explain select * from tmp where a > 1;
假設a字段是個Clustering Key,此時我們在explain查詢的執行計划中可以看見有一個Cluster Filter,表示我們已經用上Clustering Key。

(八)判斷是否用上Bitmap

接下來我們判斷是否用上Bitmap。
image.png
如上圖所示,我們的查詢條件是:
explain select * from tmp where c = 1;
這個c是Bitmap Key,在執行計划可以看到有Bitmap Filter:(c = 1)這樣一個過濾條件,此時我們就知道用上Bitmap了。

(九)判斷是否用上Segment Key

接下來判斷是否用上Segment Key。
image.png
如上圖所示,我們的查詢條件是:
explain select * from tmp where b > 1;
這個b是Segment Key,我們在執行計划可以看到有Segment Filter:(b > 1)這樣一個過濾條件,此時我們就知道用上Segment Key了。
通過以上幾個explain查詢的例子,我們就能知道查詢是否用上之前建表的Index,如果沒用上,說明有可能建表不對,或者查詢模式並沒有很好地適配建表。

(十)聯邦查詢優化

image.png
在Hologres內部有兩套計算引擎,其中一套是完全自研的Holo計算引擎,它的性能卓越,但也是因為它是完全自研的,所以相較於開源的Postgres計算引擎,它無法在一開始就支持所有Postgres的功能,會有部分Postgres功能缺失。
另一套計算引擎是Postgres,它是完全開源生態的,性能方面比自研的計算引擎稍差一些,但是它完全兼容Postgres功能。
因此,在Hologres里面,一個查詢有可能會既用到Holo計算引擎,也用到Postgres計算引擎。

(十一)優化聯邦查詢

判斷是否使用了聯邦查詢,我們可以通過explain。
Hologres自研引擎不支持not in,對於查詢:
explain select * from tmp where a not in (select a from tmp1);
如下所示:
image.png
從執行計划可以看到有External SQL(Postgres):這樣的一個算子,這就標識了查詢引擎跑到了Postgres引擎上面去執行。
因為Holo計算引擎不支持not in,所以說這部分的計算是在Postgres上面執行的。當看見External SQL(Postgres):這個算子,用戶需要警惕當下用到了Holo計算引擎不支持的功能,此時最好通過查詢改寫,換成Holo支持的算子來執行它的Query,從而提升查詢性能。
對於上面這個例子的場景,我們可以通過將not in 改為 not exist:
explain select * from tmp where not exists (select a from tmp1 where a = tmp.a);
image.png
當用戶這個表一定是非空,那么可以把not in直接改成not exit,之后再查看執行情況,會發現整個Query都是在Holo引擎上面,沒看到剛才的External SQL(Postgres)算子。
這個查詢生成的執行計划相比之前在Postgres引擎上執行的計划,查詢性能上可能會有數倍的差別。
通過上述所有的例子,我們就了解了Hologres性能調優整個過程,以及其中需要注意的關鍵點,歡迎感興趣的同學多多關注與使用Hologres。

原文鏈接

本文為阿里雲原創內容,未經允許不得轉載。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM