IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 【SQL编程】Greenplum 实现树结构+自定义函数+避免函数重复调用+ function cannot execute on a QE slice 问题处理(优化过程全记录) -> 正文阅读

[大数据]【SQL编程】Greenplum 实现树结构+自定义函数+避免函数重复调用+ function cannot execute on a QE slice 问题处理(优化过程全记录)

1.需求说明

这是一个关于POI的应用,数据从水经微图下载而来,需要处理的是街道层级的数据,但是最终的POI信息要有省、市、县数据,所有需要用到行政区划表来补全数据。

2.编程实例

2.1 实现树结构

首先看一下具有树结构的数据:

在这里插入图片描述
通过 WITH RECURSIVE table_name AS 实现递归查询树结构数据【这里要特别注意一下 t0 和 t1 表】:

WITH RECURSIVE t1 AS (
	SELECT "level", parent_code, area_code, "name" 
	FROM data_divisions 
	WHERE "name" = '枫杨街道' 
	UNION ALL
	SELECT t0."level", t0.parent_code, t0.area_code, t0."name" 
	FROM data_divisions t0, t1 
	WHERE t0.area_code = t1.parent_code 
	) 
	SELECT "level", "name" FROM t1

结果验证:
在这里插入图片描述

2.2 自定义函数

使用STRING_AGG把省市县数据拼接成一个字段【函数等价于GROUP_CONCAT】:

SELECT
	STRING_AGG ( "name", ',' ORDER BY "level" ) AS "divisions" FROM   
( WITH RECURSIVE t1 AS (
	SELECT "level", parent_code, area_code, "name" 
	FROM data_divisions 
	WHERE "name" = '枫杨街道' 
	UNION ALL
	SELECT t0."level", t0.parent_code, t0.area_code, t0."name" 
	FROM data_divisions t0, t1 
	WHERE t0.area_code = t1.parent_code 
	) 
	SELECT "level", "name" FROM t1 ) t2

在这里插入图片描述

创建自定义函数:

CREATE OR REPLACE FUNCTION getdivisionsbyname ( TEXT ) RETURNS TEXT AS $BODY$ 
	
	SELECT
	STRING_AGG ( "name", ',' ORDER BY "level" ) AS "divisions" FROM   
( WITH RECURSIVE t1 AS (
	SELECT "level", parent_code, area_code, "name" 
	FROM data_divisions 
	WHERE "name" = '枫杨街道' 
	UNION ALL
	SELECT t0."level", t0.parent_code, t0.area_code, t0."name" 
	FROM data_divisions t0, t1 
	WHERE t0.area_code = t1.parent_code 
	) 
	SELECT "level", "name" FROM t1 ) t2;

$BODY$ LANGUAGE SQL IMMUTABLE STRICT COST 100;

函数调用测试:

SELECT getDivisionsByName('枫杨街道');

在这里插入图片描述

2.3 函数使用

data_address_point 表的记录数是261条,执行耗时119.451s,这效率明显是由于多次调用自定义函数导致的 😢

SELECT  
	getdivisionsbyname(zone_name) || NAME AS "poi",
	SPLIT_PART( coordinates, ',', 1 ) AS "longitude",
	SPLIT_PART( coordinates, ',', 2 ) AS "latitude",
	NAME AS "address",
	SPLIT_PART( getdivisionsbyname(zone_name), ',', 1 ) AS "prov",
	SPLIT_PART( getdivisionsbyname(zone_name), ',', 2 ) AS "city",
	SPLIT_PART( getdivisionsbyname(zone_name), ',', 3 ) AS "district",
	SPLIT_PART( getdivisionsbyname(zone_name), ',', 4 ) AS "town" 
FROM data_address_point;

在这里插入图片描述
避免多次调用相同的自定义函数,优化后耗时23.634s,是之前的5分之1:

WITH t1 AS ( SELECT getdivisionsbyname ( zone_name ) AS "divisions", coordinates, "name", poi_type FROM data_address_point ) 
SELECT 
ROW_NUMBER ( ) OVER ( ORDER BY "name" ) AS "id",
REPLACE ( divisions, ',', '' ) || "name" AS "poi",
poi_type,
SPLIT_PART( coordinates, ',', 1 ) AS "longitude",
SPLIT_PART( coordinates, ',', 2 ) AS "latitude",
NAME AS "address",
SPLIT_PART( divisions, ',', 1 ) AS "prov",
SPLIT_PART( divisions, ',', 2 ) AS "city",
SPLIT_PART( divisions, ',', 3 ) AS "district",
SPLIT_PART( divisions, ',', 4 ) AS "town" 
FROM
	t1

在这里插入图片描述

3.报错问题

实际上,上边的函数使用并是非顺利的,第一次进行查询时报错function cannot execute on a QE slice because it accesses relation

WITH t1 AS ( SELECT getdivisionsbyname ( zone_name ) AS "divisions", coordinates, "name", poi_type FROM data_address_point ) 
SELECT 
ROW_NUMBER ( ) OVER ( ORDER BY "name" ) AS "id",
REPLACE ( divisions, ',', '' ) || "name" AS "poi",
poi_type,
SPLIT_PART( coordinates, ',', 1 ) AS "longitude",
SPLIT_PART( coordinates, ',', 2 ) AS "latitude",
NAME AS "address",
SPLIT_PART( divisions, ',', 1 ) AS "prov",
SPLIT_PART( divisions, ',', 2 ) AS "city",
SPLIT_PART( divisions, ',', 3 ) AS "district",
SPLIT_PART( divisions, ',', 4 ) AS "town" 
FROM
	t1
> ERROR:  function cannot execute on a QE slice because it accesses relation "public.data_divisions"  (seg0 slice1 192.168.0.123:6000 pid=168995)
CONTEXT:  SQL function "getdivisionsbyname" during startup

UDF(User Defined Function)用户自定义函数在 segment 上不能访问任何表。由于 MPP 的特性,任何 segment 仅仅包含部分数据,因而在 segment 执行的 UDF 不能访问任何表,否则数据计算错误。Greenplum 支持另一种分布策略:复制表,即整张表在每个节点上都有一个完整的拷贝。可使用以下命令进行设置:

ALTER TABLE table_name SET DISTRIBUTED REPLICATED;

数据量大的表不适合使用复制表模式,一些不经常变动的数据量比较小的比如码表可以使用DISTRIBUTED REPLICATED模式,查询性能也会有明显的提升。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章           查看所有文章
加:2022-03-06 13:08:12  更:2022-03-06 13:12:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:38:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码