詳解GaussDB(DWS) explain分佈式執行計劃

摘要:本文主要介紹如何詳細解讀GaussDB(DWS)產生的分佈式執行計劃,從計劃中發現性能調優勢。

前言

執行計劃(又稱解釋計劃)是數據庫執行SQL語句的具體步驟,例如經過索引仍是全表掃描訪問表中的數據,鏈接查詢的實現方式和鏈接的順序等。若是 SQL 語句性能不夠理想,咱們首先應該查看它的執行計劃。本文主要介紹如何詳細解讀GaussDB(DWS)產生的分佈式執行計劃,從計劃中發現性能調優勢。node

一、執行算子介紹

要讀懂執行計劃,首先要知道數據庫執行算子的概念:數據庫

下面重點介紹下基於sharing nothing的分佈式計劃中最重要的一類算子——STREAM算子網絡

三種類型的stream算子分佈式

1) Gather Stream (N:1) – 每一個源結點都將其數據發送給目標結點oop

2) Redistribute Stream (N:N) – 每一個源節點將其數據根據鏈接條件計算Hash值,根據從新計算的Hash值進行分佈,發給對應的目標節點性能

3) Broadcast Stream (1:N) – 由一個源節點將其數據發給N個目標節點優化

其中1)主要用於CN與DN間的數據交換,2)與3)主要用於DN間的數據交換ui

二、EXPLAIN用法

SQL執行計劃是一個節點數,顯示執一條SQL語句執行時的詳細步驟。每個步驟是一個數據庫運算符,也叫做一個執行算子。使用explain命令能夠查看優化器爲每一個查詢生成的具體執行計劃。spa

1) EXPLAIN的語法線程

其中,option中COSTS與NODES的默認值爲ON,其餘參數默認爲OFF。

說明:

a) EXPLAIN + QUERY並不會真正執行,只會將計劃打印出來,指定option中的ANALYZE能夠進行實際執行

b) PERFORMANCE 選項默認會將全部的選項置爲ON,即顯示全部的執行信息。

c) CPU/BUFFER/DETAIL 選項依賴於ANALYZE,只有ANALYZE置爲ON的時候,才能使用這幾個選項。

d) DETAIL選項用來控制輸出,DETAIL 置爲ON時,會顯示各個DN上具體的執行信息;DATAIL 置爲OFF時,顯示全部DN的彙總信息,即最大最小值信息。

2) EXPLAIN顯示格式

GaussDB中提供了兩種顯示格式(normal/pretty),經過設置參數explain_perf_mode進行控制。其中,normal格式爲默認的顯示格式。

normal格式以下:

pretty格式以下:

改進後的顯示格式,層次清晰,計劃包含了plan node id,性能分析會更加簡單直接。

使用以前可使用show explain_perf_mode;來查看當前數據庫使用的顯示風格。

同時可使用set explain_perf_mode=pretty/normal;來設置輸出的格式。

三、示例計劃解讀(每一個算子資源消耗、耗時等等)

1) 四中常見類型計劃

建表語句:

a) FQS計劃,徹底下推,下發query

兩表JOIN,且其鏈接條件爲各表的分佈列,在關閉stream算子的狀況下,CN會直接將該語句發送至各DN執行,最後結果在CN彙總。

b) 非FQS計劃,部分語句下推

兩表JOIN,且鏈接條件中包含非分佈列,此時在關閉stream算子的狀況下,CN會將基表掃描語句下發至各DN,而後在CN上進行JOIN。

c) Stream計劃,DN之間無數據交換

兩表JOIN,且鏈接條件爲各表的分佈列,所以各DN無需數據交換。CN生成stream計劃後,將除Gather Stream的計劃下發給DN執行,在各個DN上進行基表 掃描,並進行哈希鏈接後,發送給CN。

d) Stream計劃,DN之間存在數據交換

兩表JOIN,且鏈接條件包含非分佈列,在開啓stream算子的狀況下,會生成stream計劃,其DN間存在數據交換。此時對於tt02表,會在各DN進行基表掃描,掃描後會經過Redistribute Stream算子,按照JOIN條件中的tt02.c1進行哈希計算後從新發送給各DN,而後在各DN上作JOIN,最後彙總到CN。

2) explain performance詳解

a) 執行計劃

•id:執行算子節點編號。

•operation:具體的執行節點算子名稱。

•A-time:各DN相應算子執行時間,[]中左側爲最小值,右側爲最大值,包括下層算子執行時間。

•A-rows:相應算子輸出的全局總行數。

•E-rows:每一個算子估算的輸出行數。

•Peak Memory:各DN相應算子消耗內存峯值,[]中左側爲最小值,右側爲最大值。

•E-memory:DN上每一個算子估算的內存使用量,只有DN上執行的算子會顯示。某些場景會在估算的內存使用量後使用括號顯示該算子在內存源充足下能夠自動擴展的內存上限。

•E-width:每一個算子輸出元組的估算寬度。

•E-costs:每一個算子估算的執行代價。

b) 謂詞過濾

顯示對應執行算子節點的過濾條件

c) 內存使用

主要顯示CN的最大內存用量、DN最大內存用量、各算子的最大內存用量、各算子預估內存用量、Stream線程的啓動以及收發時間。

d) Targetlist Information

各個算子對應的輸出目標列信息。

e) DN信息

各算子的執行時間、Buffer、CPU信息

f) 自定義信息

CN與DN之間的建連信息、DN與DN之間的建連信息。

g) 彙總信息

    • DN執行器開始時間,[min_node_name, max_node_name] : [min_time, max_time]
    • DN執行器結束時間,[min_node_name, max_node_name] : [min_time, max_time]
    • Remote query poll time:接收結果時用於poll等待的時間
    • CN執行器開始、運行及結束時間
    • 網絡流量,stream算子發送的數據量
    • 優化器執行期時間
    • 查詢ID
    • 總執行時間

h) 執行時間介紹

每一個算子的執行信息都包含三個部分:

其中:

      • dn_6001_6002/dn_6003_6004 表示具體執行的節點信息,括號中的信息是實際的執行信息
      • actual time=0.013..2290.971 表示實際的執行時間

第一個數字表示執行時進入當前算子到輸出第一條數據所花費的時間

第二個數字爲輸出全部數據的總執行時間

注意:在整個計劃中,除了葉子節點的執行時間是算子自己的執行時間,其他算子的執行時間均包含子節點的執行時間。

在該計劃中,7號節點和9號節點爲葉子節點,其他節點均爲非葉子簡介。1號節點時頂層節點,因此該節點的執行時間就能夠做爲整個查詢的執行時間。

      • rows=2001550 表示當前算子輸出數據爲2001550行;
      • loops=1 表示當前算子的只執行了一次,而對於分區表的掃描(7號節點)來講:

該層掃描算子的loops爲7,對於分區表,每個分區表的掃描就是一次完整的掃描操做,當切換到下一個分區的時候,又是一次新的查詢操做,查詢該表定義以下:

Inventory表有7個分區,因此就執行了7次表掃描操做,所以loops=7。

i) CPU信息介紹

每一個算子執行的過程都有CPU信息,其中cyc表明的是CPU的週期數,ex cyc表示的是當前算子的週期數,不包含其子節點;inc cyc是包含子節點的週期數;ex row是當前算子輸出的數據行數;ex c/r則是ex cyc/ex row獲得的每條數據所用的平均週期數。

j) Buffer信息介紹

buffers顯示緩衝區信息,包括共享塊和臨時塊的讀和寫。

共享塊包含表和索引,臨時塊在排序和物化中使用的磁盤塊。上層節點顯示出來的塊數據包含了其全部子節點使用的塊數。

Buffers涉及的參數有兩種,分別爲:shared和temp,及shared hit/read/dirtied/written以及temp read/write

Hit blocks:表明從磁盤裏面讀到的數據塊數

Dirtied blocks:表明當前查詢中被修改了的而且此前未被修改的數據塊數

Written blocks:表明當前線程將shared bufer裏被修改的數據寫回到磁盤的塊數

k) 執行內存

其中:

Peak Memory:5KB 表示當前算子實際執行時使用的峯值內存;

Estimate Memory:1024MB 表示預估的內存,爲優化器給出的預估值。

l) 其餘執行信息

(1)sort 算子,會顯示排序信息

Sort Method表明排序的方法,包括quicksort(快排)和disksort(外排)。快排即內存夠用時,全部的排序操做均在內存中完成,外排說明當前可用內存不足,須要下盤。

(2)hashjoin算子

Buckets:表明hash表中實際使用的桶的個數

Batches:表明hashjoin中實際分塊的數量。若是Batches=1,則說明全部的數據全在內存中,沒有下盤操做;反之則說明有下盤操做,Batches - 1表明臨時文件的個數。

Memory Usage:就是hashjoin中內存的使用狀況

(3)hashagg算子

若是發生數據下盤,會有File Num:512信息,顯示臨時文件的個數。

(4)stream算子

stream算子的會統計當前算子處理數據的字節數,其從子線程獲取數據的時間(poll time)以及處理數據的時間(Deserialize Time)。

stream算子的子節點會統計發送端的時間信息,以下:

發送時間Send time,排隊時間Wait Quota time, OS發送時間以及數據處理的時間。

3) explain 調優示例

一個查詢語句要通過多個算子步驟纔會輸出最終的結果。因爲個別算子耗時過長致使總體查詢性能降低的狀況比較常見。這些算子是整個查詢的瓶頸算子。通用的優化手段是EXPLAIN ANALYZE/PERFORMANCE命令查看執行過程的瓶頸算子,而後進行鍼對性優化。

基表掃描時,對於點查或者範圍掃描等過濾大量數據的查詢,若是使用SeqScan全表掃描會比較耗時,能夠在條件列上創建索引選擇IndexScan進行索引掃描提高掃描效率。以下示例:

上述例子中,全表掃描返回3360條數據,過濾掉大量數據,在sssolddate_sk列上創建索引後,使用IndexScan掃描效率顯著提升,從960毫秒提高到8毫秒。

結語:

在調優過程當中,熟練使用explain並能分析各部分數據結果是很是重要的。本文中僅僅介紹了大多數字段的含義以及根據explain結果進行調優的一個小示例,還能夠與plan hint結合使用找出執行的最佳路徑,也能夠定位傾斜程度等等。

 

點擊關注,第一時間瞭解華爲雲新鮮技術~

相關文章
相關標籤/搜索