報錯信息:
在Greenplum數據庫中,我們使用存儲過程查詢數據的時候會報錯如下信息
function cannot execute on a QE slice because it accesses relation
首先我們先了解下復制表
復制表(Replicated Table)
Greenplum 6支持一種新的分布策略:復制表,即整張表在每個節點上都有一個完整的拷貝。
test=# CREATE TABLE t2 (id int) DISTRIBUTED REPLICATED; CREATE TABLE test=# INSERT INTO t2 VALUES (1), (2), (3); INSERT 0 3 test=# SELECT * FROM t2; id ---- 1 2 3 (3 rows) test=# SELECT gp_segment_id, * from t2; gp_segment_id | id ---------------+---- 0 | 1 0 | 2 0 | 3
UDF 在 segment 上不能訪問任何表。由於 MPP 的特性,任何 segment 僅僅包含部分數據,因而在 segment 執行的 UDF 不能訪問任何表,否則數據計算錯誤。
yydzero=# CREATE FUNCTION c() RETURNS bigint AS $$ yydzero$# SELECT count(*) from t1 AS result; yydzero$# $$ LANGUAGE SQL; CREATE FUNCTION yydzero=# SELECT c(); c --- 6 (1 row) yydzero=# select c() from t2; ERROR: function cannot execute on a QE slice because it accesses relation "public.t1" (seg0 slice1 192.168.1.107:25435 pid=76589)
如果把上面的t1改成復制表,則不存在這個問題。
避免分布式查詢計划:
如果一張表的數據在各個segment上都有拷貝,那么就可以生成本地連接計划,而避免數據在集群的不同節點間移動。如果用復制表存儲數據量比較小的表(譬如數千行),那么性能有明顯的提升。 數據量大的表不適合使用復制表模式。
解決方案
找到了原因,就簡單了,只需要修改建表語句即可解決問題
ALTER TABLE table_name SET DISTRIBUTED REPLICATED;
參考文檔