本文介紹AnalyticDB PostgreSQL版如何選擇表分布策略。
選擇表分布策略
AnalyticDB PostgreSQL支援雜湊(HASH)分布、隨機(RANDOMLY)分布、複製(REPLICATED)分布三種分布方式。
CREATE TABLE <table_name> (...) [ DISTRIBUTED BY (<column> [,..] ) | DISTRIBUTED RANDOMLY | DISTRIBUTED REPLICATED ]
AnalyticDB PostgreSQL版4.3版本只支援雜湊(HASH)分布和隨機(RANDOMLY)分布,複製(REPLICATED)分布為AnalyticDB PostgreSQL版6.0版本新增特性。
建表語句CREATE TABLE
支援如下三個分布策略的子句:
分布方式 | 說明 |
雜湊分布
| 資料將根據分布列的雜湊值將各個行分布到指定計算節點上,相同的雜湊值會始終散列到同一計算節點。為保障資料可以均勻分布在各個節點上,建議您選擇唯一鍵(例如主鍵)作為分布鍵。 AnalyticDB PostgreSQL版的預設分布策略為雜湊分布,如果建表時未指定DISTRIBUTED子句,系統會選擇主鍵或表的第一個合適的列作為分布鍵。如果表中沒有合適的列,系統將會使用隨機分布策略。 |
隨機分布
| 系統會按迴圈的方式將資料分布到各個計算節點上,但是相同值的資料可能不會分布到同一個計算節點。 隨機分布僅建議您在沒有合適的列作為分布列時使用。 |
複製分布
| 系統會在每個計算節點都儲存一份表的全量資料。 如果資料庫中存在大表與小表join的情境,您可以將足夠小的表設定為複製分布來提升效能。 |
樣本如下:
雜湊分布
CREATE TABLE products (name varchar(40), prod_id integer, supplier_id integer) DISTRIBUTED BY (prod_id);
隨機分布
CREATE TABLE random_stuff (things text, doodads text, etc text) DISTRIBUTED RANDOMLY;
複製分布
CREATE TABLE replicated_stuff (things text, doodads text, etc text) DISTRIBUTED REPLICATED;
AnalyticDB PostgreSQL支援節點裁剪功能,對於按分布鍵的簡單查詢(包括UPDATE和DELETE等語句),支援按節點的分布鍵進行資料節點裁剪。例如products表的分布鍵為prod_id列,以下查詢語句只會被發送到滿足prod_id=101
的計算節點上執行,可以有效提升該查詢的執行效能。
select * from products where prod_id = 101;
表分布鍵選擇原則
合理規劃分布鍵,對錶查詢的效能至關重要,有以下原則需要關註:
盡量選擇資料分布均勻的列作為分布鍵,若分布鍵資料分布不均勻,可能會導致資料扭曲。資料扭曲會導致部分計算節點儲存的資料過多,查詢負載大,查詢耗時變長。因此請不要選擇bool類型、時間日期類型的列作為分布鍵。
選擇經常作為查詢條件的列作為分布鍵,可以實現按分布鍵進行節點裁剪。
您可以選擇一個或多個列作為分布鍵,樣本如下:
create table t1(c1 int, c2 int) distributed by (c1,c2);
盡量不要選擇隨機分布。使用隨機分布將無法使用本地關聯以及節點裁剪等功能。
選擇經常需要JOIN的列作為分布鍵,可以實現本地關聯(Collocated JOIN)計算(如圖一所示),因為JOIN鍵和分布鍵一致時,可以在計算節點內部完成JOIN。否則需要將一個表進行重分布(Redistribute motion)來實現重分布關聯(Redistributed Join)(如圖二所示)或者廣播其中小表(Broadcast motion)來實現廣播關聯(Broadcast Join)(如圖三所示),重分布關聯和廣播關聯兩種方式都會產生較大的網路開銷。
表分布鍵的約束
分布鍵的列不能被更新(UPDATE)。
主鍵和唯一鍵必須包含分布鍵。例如:
create table t1(c1 int, c2 int, primary key (c1)) distributed by (c2);
說明由於主鍵c1不包含分布鍵c2,所以建表語句返回失敗。
ERROR: PRIMARY KEY and DISTRIBUTED BY definitions incompatible
Geometry類型和使用者自訂資料類型不能作為分布鍵。
資料扭曲檢查和處理
當某些表上的查詢效能差時,可以查看是否是分區鍵設定不合理造成了資料扭曲,例如:
create table t1(c1 int, c2 int) distributed by (c1);
您可以通過下述語句來查看錶的資料扭曲情況。
select gp_segment_id,count(1) from t1 group by 1 order by 2 desc;
gp_segment_id | count
---------------+--------
2 | 131191
0 | 72
1 | 68
(3 rows)
如果發現某些 Segment上儲存的資料明顯多於其他 Segment,該表存在資料扭曲。建議選取資料分布平均的列作為分布列,比如通過ALTER TABLE
命令更改C2為分布鍵。
alter table t1 set distributed by (c2);
表t1的分布鍵被改為c2,該表的資料按照c2被重新分配,資料不再傾斜。