PolarDB PostgreSQL版支援ePQ查看與分析執行計畫。
背景資訊
PostgreSQL提供了EXPLAIN命令用於SQL語句的效能分析,該命令可以輸出SQL對應的查詢計劃,以及在執行過程中的具體耗時、資源消耗等資訊,可用於排查SQL的效能瓶頸。
但EXPLAIN命令只適用於單機執行的SQL效能分析,PolarDB PostgreSQL版的ePQ擴充了EXPLAIN的功能,使其可以列印ePQ的跨機並存執行計劃,還可以統計ePQ執行計畫在各個運算元上的執行時間、資料掃描量、記憶體使用量等資訊,並以統一的視角提供給使用者。
前提條件
支援的PolarDB PostgreSQL版的版本如下:
PostgreSQL 11(核心小版本1.1.22及以上)
PostgreSQL 14(核心小版本14.6.6.0及以上)
您可通過如下語句查看PolarDB PostgreSQL版的核心小版本的版本號碼:
PostgreSQL 11
show polar_version;PostgreSQL 14
select version();
原理介紹
ePQ查詢的發起進程(QC)與背景工作處理序(Worker)之間採用libpq的Y協議進行通訊:
QC將
EXPLAIN ANALYZE命令下發給Worker。各個Worker進程統計本進程內的資源使用、執行耗時等資訊。
各個Worker在完成計劃分區的執行後,將統計資訊發送給QC。
QC等待所有Worker進程完成各自執行後,進行統計計算並輸出。
功能介紹
執行計畫查看
ePQ的執行計畫是分區的。每個計劃分區(Slice)由計算節點上的虛擬執行單元(Segment)啟動的一組進程(Gang)負責執行,完成SQL的一部分計算。ePQ在執行計畫中引入了Motion運算元,用於在執行不同計劃分區的進程組之間進行資料傳遞。因此,Motion運算元是計劃分區的邊界。
ePQ中總共引入了三種Motion運算元:
PX Coordinator:源端資料發送到同一個目標端(匯聚)。PX Broadcast:源端資料發送到每一個目標端(廣播)。PX Hash:源端資料經過雜湊計算後發送到某一個目標端(重分布)。
樣本
以下為一個簡單查詢樣本:
CREATE TABLE t (id INT); SET polar_enable_px TO ON; EXPLAIN (COSTS OFF) SELECT * FROM t LIMIT 1; QUERY PLAN ------------------------------------------------- Limit -> PX Coordinator 6:1 (slice1; segments: 6) -> Partial Seq Scan on t Optimizer: PolarDB PX Optimizer (4 rows)以上執行計畫以Motion運算元為界,被分為了兩個分區:一個是接收最終結果的分區
slice0,一個是掃描資料的分區slice1。對於
slice1計劃分區,ePQ將使用六個執行單元(segments: 6)分別啟動一個進程來執行,這六個進程各自負責掃描表的一部分資料(Partial Seq Scan),通過Motion運算元將六個進程的資料匯聚到一個目標端(PX Coordinator 6:1),傳遞給Limit運算元。如果查詢逐漸複雜,則執行計畫中的計劃分區和Motion運算元會越來越多,樣本如下:
CREATE TABLE t1 (a INT, b INT, c INT); SET polar_enable_px TO ON; EXPLAIN (COSTS OFF) SELECT SUM(b) FROM t1 GROUP BY a LIMIT 1; QUERY PLAN ------------------------------------------------------------ Limit -> PX Coordinator 6:1 (slice1; segments: 6) -> GroupAggregate Group Key: a -> Sort Sort Key: a -> PX Hash 6:6 (slice2; segments: 6) Hash Key: a -> Partial Seq Scan on t1 Optimizer: PolarDB PX Optimizer (10 rows)以上執行計畫中總共有三個計劃分區。將會有六個進程(
segments: 6)負責執行slice2分區,分別掃描表的一部分資料,然後通過Motion運算元(PX Hash 6:6)將資料重分布到另外六個(segments: 6)負責執行slice1分區的進程上,各自完成排序(Sort)和彙總(GroupAggregate),最終通過Motion運算元(PX Coordinator 6:1)將資料匯聚到結果分區slice0。
執行計畫分析
EXPLAIN中的ANALYZE選項會使查詢被真正執行,並收集執行過程中的各項統計資訊,而不僅僅是列印執行計畫。在ePQ的執行計畫中,同一個運算元會被一組進程執行。因此,ePQ的EXPLAIN ANALYZE需要收集執行同一個運算元的所有進程的統計資訊。
運算元層級的統計資訊如下:
運算元執行時間:取執行該運算元的所有進程的最長執行時間。
運算元掃描總行數:取執行該運算元的所有進程的掃描行數累加和。
運算元執行次數(迴圈):取執行該運算元的所有進程的迴圈次數累加和。
運算元的資源使用資訊:取執行該運算元的所有進程的資源使用量累加和。
此外,ePQ的EXPLAIN ANALYZE還可以收集執行同一運算元的各進程層級的統計資訊,可被用於判斷計劃執行過程中是否存在傾斜。具體包含資訊如下:
每個進程的記憶體使用量情況。
每個進程的執行時間。
每個進程的處理行數。
樣本
建立一張表並插入資料。
CREATE TABLE t2 (a INT, b INT, c VARCHAR(20)); INSERT INTO t2 SELECT i, i*2, to_char(i, 'FM00000') FROM generate_series(1, 100000) i;設定如下參數並執行
EXPLAIN ANALYZE。SET polar_enable_px TO ON; SET polar_px_enable_explain_all_stat TO ON; SET polar_px_explain_memory_verbosity TO detail; EXPLAIN (COSTS OFF, ANALYZE) SELECT * FROM t2; QUERY PLAN ------------------------------------------------------------------------------------------- PX Coordinator 6:1 (slice1; segments: 6) (actual time=0.816..54.225 rows=100000 loops=1) Executor Memory: 9kB Workers: 1 Max: 9kB (worker -1) -> Partial Seq Scan on t2 (actual time=0.052..24.732 rows=94720 loops=1) Executor Memory: 326kB Workers: 6 Max: 145kB (worker 1) allstat: worker:0, first_time:7.396(ms), total_time:25(ms), total_num:94720 worker:1, first_time:7.396(ms), total_time:2.819(ms), total_num:5280 worker:2, first_time:7.393(ms), total_time:0.074(ms), total_num:0 worker:3, first_time:7.400(ms), total_time:0.078(ms), total_num:0 worker:4, first_time:7.402(ms), total_time:0.086(ms), total_num:0 worker:5, first_time:7.399(ms), total_time:0.098(ms), total_num:0 Dynamic Pages Per Worker: [512,29] Planning Time: 9.768 ms Optimizer: PolarDB PX Optimizer (slice0) Executor memory: 38K bytes. (slice1) Executor memory: 68K bytes avg x 6 workers, 164K bytes max (seg1). Execution Time: 65.572 ms (17 rows)在上述執行計畫中:
每個運算元下的
Executor Memory部分列印了執行這個運算元的所有進程所使用的總記憶體量、進程數量以及使用記憶體量最大的進程編號。allstat部分列印了執行運算元的每一個進程的準備時間(first_time)、執行時間(total_time)和處理元組數量(total_num)。