關聯數據在不一樣節點上,對於普通關係型數據庫來講,是沒法進行鏈接的。關聯的數據須要經過網絡流入到一個節點中進行計算,這樣就須要發生數據遷移。數據遷移有廣播和重分佈兩種。在GP中,每個廣播或重分佈會產生一個切片,每個切片在每一個數據節點上都會對應發起一個進程來處理該slice負責的數據,上一層負責該slice的進程會讀取下級slice廣播或重分佈的數據,而後進行相應的計算。html
當兩張表關聯的時候,若是有一張表的關聯鍵不是分佈鍵,那麼就會發生表的廣播或者重分佈,將數據移動到一個節點上進行關聯,從而得到數據。
分佈式的關聯有兩種:
單庫關聯:關聯鍵與分佈鍵一致,只須要但單個庫關聯後獲得結果便可。
跨庫關聯:關聯鍵與分佈鍵不一致,數據須要從新分佈。轉換成單庫關聯,從而實現表的關聯。數據庫
表關係以下:網絡
表A
字段:id,id2
分佈鍵:id
數據量:M分佈式
表B
字段:id,id2
分佈鍵:id
數據量:Nhtm
內鏈接blog
狀況1:進程
select * from A,B where A.id=B.id;
分佈鍵與關聯鍵相同,屬於單庫關聯,不會形成廣播或者重分佈。select
狀況2:數據
select * from A,B where A.id=B.id2;
表A的關聯鍵是分佈鍵,表B的關聯鍵不是分佈鍵,那麼能夠經過兩種凡是來實現關聯。
1. 將表B按照id2字段將數據重分佈到一個節點上,而後再與表A進行關聯。重分佈的數據量是N。
2. 將表A廣播,每個節點都放一份全量數據,而後再與表B關聯獲得結果。廣播的數據量是M*節點數。
因此,當N>M*節點數的時候,選擇表A廣播,不然選擇B重分佈。關係型數據庫
狀況3:
select * from A,B where A.id2=B.id2;
兩個表的關聯鍵與分佈鍵都不同,那麼還有兩種作法:
1. 將表A與表B按照id2字段,將數據重分佈到每一個節點,重分佈的代價是M+N。
2. 將其中一張表廣播後再關聯,固然選取小表廣播,代價小。廣播的代價是min(M,N)*節點數。
因此當M+N>min(M,N)*節點數的時候,選擇小表廣播,不然選擇兩個表都重分佈。
左鏈接
狀況1:
select * from A left join B on A.id=B.id;
單庫關聯,不涉及數據庫跨庫關聯。
狀況2:
select * from A left join B on A.id=B.id2;
因爲左表的分佈鍵是關聯鍵,鑑於左鏈接的性質,不管表B數據量多大,都必須將表B按照字段id2重分佈數據。
狀況3:
select * from A left join B on A.id2=B.id;
左表的關聯鍵不是分佈鍵,因爲左鏈接A表確定不是被廣播的,因此有兩種方式。
1. 將表A按照id2重分佈數據,轉換成狀況A,代價爲M。
2. 將表B廣播,代價爲N*節點數。
狀況4:
select * from A left join B on A.id2=B.id2;
有兩種處理方式。
1. 將表A與表B都按照id2字段將數據重分佈一遍以,轉換成狀況1,代價是M+N。
2. 表A不能被廣播,只能將表B廣播,代價是N*節點數。
全鏈接
狀況1:
select * from A full outer join B on A.id=B.id;
關聯鍵是分佈鍵,在GP中全鏈接只能採用Merge Join來實現。
狀況2:
select * from A full outer join B on A.id=B.id2;
將不是關聯鍵不是分佈鍵的表重分佈數據,轉換成狀況1解決。不管A、B大小分別爲多少,爲了實現全鏈接,不能講表廣播,只能是重分佈。
狀況3:
select * from A full outer join B on A.id2=B.id2;
將兩張表都重分佈,轉換成狀況1進行處理。
《Greenplum企業應用實戰》
(原文地址:http://www.jpblog.cn/greenplum-%E6%89%A7%E8%A1%8C%E8%AE%A1%E5%88%92%E4%B9%8B%E5%B9%BF%E6%92%AD%E4%B8%8E%E9%87%8D%E5%88%86%E5%B8%83.html)