Greenplum使用存储过程报错function cannot execute on a QE slice because it accesses relation

报错信息:

在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;

 

参考文档

 

posted @ 2021-12-29 14:04  zhengsongsong  阅读(2011)  评论(0编辑  收藏  举报