PolarDB PostgreSQL版的ePQ支援分區表查詢功能。
背景資訊
隨著資料量的不斷增長,表的規模將會越來越大。為了方便管理和提高查詢效能,使用者一般會使用分區表,將大表拆分成多張子分區表,每張子分區表又可以進一步拆分成二級子分區表,從而形成了多級分區表。
PolarDB PostgreSQL版支援彈性跨機並行查詢,能夠利用叢集中多個計算節點提升唯讀查詢的效能。ePQ不僅能夠對普通表進行高效的跨機並行查詢,對分區表也實現了跨機並行查詢。
ePQ對分區表支援的基礎功能如下:
對分區策略為Range/List/Hash的分區表進行並行掃描。
對分區表進行索引掃描。
對分區表進行串連查詢。
此外,ePQ還支援了部分與分區表相關的進階功能:
分區裁剪。
智能分區串連(Partition Wise Join)。
對多級分區表進行並行查詢。
ePQ暫不支援對具有多列分區鍵的分區表進行並行查詢。
前提條件
支援的PolarDB PostgreSQL版的版本如下:
PostgreSQL 11(核心小版本1.1.17及以上)
PostgreSQL 14(核心小版本14.8.11.0及以上)
您可通過如下語句查看PolarDB PostgreSQL版的核心小版本的版本號碼:
PostgreSQL 11
show polar_version;PostgreSQL 14
select version();
使用指南
分區表並行查詢
建立一張分區策略為Range的分區表,並建立三個子分區。
CREATE TABLE t1 (id INT) PARTITION BY RANGE(id); CREATE TABLE t1_p1 PARTITION OF t1 FOR VALUES FROM (0) TO (200); CREATE TABLE t1_p2 PARTITION OF t1 FOR VALUES FROM (200) TO (400); CREATE TABLE t1_p3 PARTITION OF t1 FOR VALUES FROM (400) TO (600);開啟ePQ和ePQ分區表掃描功能。
SET polar_enable_px TO ON; SET polar_px_enable_partition TO ON;查看對分區表進行全表掃描的執行計畫。
EXPLAIN (COSTS OFF) SELECT * FROM t1; QUERY PLAN ------------------------------------------- PX Coordinator 6:1 (slice1; segments: 6) -> Append -> Partial Seq Scan on t1_p1 -> Partial Seq Scan on t1_p2 -> Partial Seq Scan on t1_p3 Optimizer: PolarDB PX Optimizer (6 rows)在上述執行計畫中,ePQ將會啟動一組進程並行掃描分區表的每一個子表。每一個掃描進程都會通過
Append運算元依次掃描每一個子表的一部分資料(Partial Seq Scan),並通過Motion運算元(PX Coordinator)將所有進程的掃描結果匯聚到發起查詢的進程並返回。
分區靜態裁剪
當查詢的過濾條件中包含分區鍵時,ePQ最佳化器可以根據過濾條件對需要掃描的分區表進行裁剪,避免掃描不需要的子分區,節省系統資源,提升查詢效能。以上述t1表為例,查看以下查詢的執行計畫。
EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE id < 100;
QUERY PLAN
-------------------------------------------
PX Coordinator 6:1 (slice1; segments: 6)
-> Append
-> Partial Seq Scan on t1_p1
Filter: (id < 100)
Optimizer: PolarDB PX Optimizer
(5 rows)由於查詢的過濾條件id < 100包含分區鍵,因此ePQ最佳化器可以根據分區表的分區邊界,在產生執行計畫時去掉不符合過濾條件的子分區(t1_p2、t1_p3),只保留符合過濾條件的子分區(t1_p1)。
智能分區串連
在進行分區表之間的串連操作時,如果分區策略和邊界相同,並且串連條件為分區鍵時,ePQ最佳化器可以產生以子分區為單位進行串連的執行計畫,避免兩張分區表進行笛卡爾積式的串連,節省系統資源,提升查詢效能。
以兩張Range分區表的串連為例。
建立兩張分區策略和邊界都相同的分區表
t2和t3。CREATE TABLE t2 (id INT) PARTITION BY RANGE(id); CREATE TABLE t2_p1 PARTITION OF t2 FOR VALUES FROM (0) TO (200); CREATE TABLE t2_p2 PARTITION OF t2 FOR VALUES FROM (200) TO (400); CREATE TABLE t2_p3 PARTITION OF t2 FOR VALUES FROM (400) TO (600); CREATE TABLE t3 (id INT) PARTITION BY RANGE(id); CREATE TABLE t3_p1 PARTITION OF t3 FOR VALUES FROM (0) TO (200); CREATE TABLE t3_p2 PARTITION OF t3 FOR VALUES FROM (200) TO (400); CREATE TABLE t3_p3 PARTITION OF t3 FOR VALUES FROM (400) TO (600);開啟ePQ對分區表的支援。
SET polar_enable_px TO ON; SET polar_px_enable_partition TO ON;關閉Partition Wise join時,兩表在分區鍵上等值串連的執行計畫如下。
SET polar_px_enable_partitionwise_join TO OFF; EXPLAIN (COSTS OFF) SELECT * FROM t2 JOIN t3 ON t2.id = t3.id; QUERY PLAN ----------------------------------------------------------- PX Coordinator 6:1 (slice1; segments: 6) -> Hash Join Hash Cond: (t2_p1.id = t3_p1.id) -> Append -> Partial Seq Scan on t2_p1 -> Partial Seq Scan on t2_p2 -> Partial Seq Scan on t2_p3 -> Hash -> PX Broadcast 6:6 (slice2; segments: 6) -> Append -> Partial Seq Scan on t3_p1 -> Partial Seq Scan on t3_p2 -> Partial Seq Scan on t3_p3 Optimizer: PolarDB PX Optimizer (14 rows)從執行計畫中可以看出,執行
slice1計劃分區的六個進程會分別通過Append運算元依次掃描分區表t2每一個子分區的一部分資料,並通過Motion運算元(PX Broadcast)接收來自執行slice2的六個進程廣播的t3全表資料,在本地完成雜湊串連(Hash Join)後,通過Motion運算元(PX Coordinator)匯聚結果並返回。本質上,分區表t2的每一行資料都與t3的每一行資料做了一次串連。開啟Partition Wise join後,再次查看執行計畫。
SET polar_px_enable_partitionwise_join TO ON; EXPLAIN (COSTS OFF) SELECT * FROM t2 JOIN t3 ON t2.id = t3.id; QUERY PLAN ------------------------------------------------ PX Coordinator 6:1 (slice1; segments: 6) -> Append -> Hash Join Hash Cond: (t2_p1.id = t3_p1.id) -> Partial Seq Scan on t2_p1 -> Hash -> Full Seq Scan on t3_p1 -> Hash Join Hash Cond: (t2_p2.id = t3_p2.id) -> Partial Seq Scan on t2_p2 -> Hash -> Full Seq Scan on t3_p2 -> Hash Join Hash Cond: (t2_p3.id = t3_p3.id) -> Partial Seq Scan on t2_p3 -> Hash -> Full Seq Scan on t3_p3 Optimizer: PolarDB PX Optimizer (18 rows)在上述執行計畫中,執行
slice1計劃分區的六個進程將通過Append運算元依次掃描分區表t2每個子分區中的一部分資料,以及分區表t3相對應子分區的全部資料,將兩份資料進行雜湊串連(Hash Join),最終通過Motion運算元(PX Coordinator)匯聚結果並返回。在上述執行過程中,分區表
t2的每一個子分區t2_p1、t2_p2、t2_p3分別只與分區表t3對應的t3_p1、t3_p2、t3_p3做了串連,並沒有與其它不相關的分區串連,提高了效率。
多級分區表並行查詢
在多級分區表中,每級分區表的分區維度(分區鍵)可以不同:例如,一級分區表按照時間維度分區,二級分區表按照地區維度分區。當查詢SQL的過濾條件中包含每一級分區表中的分區鍵時,ePQ最佳化器支援對多級分區表進行靜態分區裁剪,從而過濾掉不需要被掃描的子分區。
如下圖所示:當查詢過濾條件WHERE date = '202201' AND region = 'beijing'中包含一級分區鍵date和二級分區鍵region時,ePQ最佳化器能夠裁剪掉所有不相關的分區,產生的執行計畫中只包含合格子分區。由此,執行器只對需要掃描的子分區進行掃描。
樣本
建立一張多級分區表。
CREATE TABLE r1 (a INT, b TIMESTAMP) PARTITION BY RANGE (b); CREATE TABLE r1_p1 PARTITION OF r1 FOR VALUES FROM ('2000-01-01') TO ('2010-01-01') PARTITION BY RANGE (a); CREATE TABLE r1_p1_p1 PARTITION OF r1_p1 FOR VALUES FROM (1) TO (1000000); CREATE TABLE r1_p1_p2 PARTITION OF r1_p1 FOR VALUES FROM (1000000) TO (2000000); CREATE TABLE r1_p2 PARTITION OF r1 FOR VALUES FROM ('2010-01-01') TO ('2020-01-01') PARTITION BY RANGE (a); CREATE TABLE r1_p2_p1 PARTITION OF r1_p2 FOR VALUES FROM (1) TO (1000000); CREATE TABLE r1_p2_p2 PARTITION OF r1_p2 FOR VALUES FROM (1000000) TO (2000000);開啟ePQ對分區表的支援。
SET polar_enable_px TO ON; SET polar_px_enable_partition TO ON;執行一條以兩級分區鍵作為過濾條件的SQL,並關閉ePQ的多級分區掃描功能,得到PostgreSQL內建最佳化器經過多級分區靜態裁剪後的執行計畫。
SET polar_px_optimizer_multilevel_partitioning TO OFF; EXPLAIN (COSTS OFF) SELECT * FROM r1 WHERE a < 1000000 AND b < '2009-01-01 00:00:00'; QUERY PLAN ---------------------------------------------------------------------------------------- Seq Scan on r1_p1_p1 r1 Filter: ((a < 1000000) AND (b < '2009-01-01 00:00:00'::timestamp without time zone)) (2 rows)開啟ePQ的多級分區掃描功能,再次查看執行計畫。
SET polar_px_optimizer_multilevel_partitioning TO ON; EXPLAIN (COSTS OFF) SELECT * FROM r1 WHERE a < 1000000 AND b < '2009-01-01 00:00:00'; QUERY PLAN ---------------------------------------------------------------------------------------------------- PX Coordinator 6:1 (slice1; segments: 6) -> Append -> Partial Seq Scan on r1_p1_p1 Filter: ((a < 1000000) AND (b < '2009-01-01 00:00:00'::timestamp without time zone)) Optimizer: PolarDB PX Optimizer (5 rows)在上述計劃中,ePQ最佳化器進行了對多級分區表的靜態裁剪。執行
slice1計劃分區的六個進程只需對符合過濾條件的子分區r1_p1_p1進行並行掃描(Partial Seq Scan),並將掃描到的資料通過Motion運算元(PX Coordinator)匯聚並返回。