GaussDB(DWS)性能调优:函数下推
【摘要】 DWS作为MPP架构的数仓产品,其性能优势主要在分布式计算上。默认情况下,DWS为了保证结果的正确性,自定义函数默认属性是不下推的,这会导致计算不下推,从而导致比较验证的性能问题。本文主要描述下函数在满足特征的前提下可以把函数属性定义为下推属性
1.前言
DWS作为MPP架构的数仓产品,其性能优势主要在分布式计算上。默认情况下,DWS为了保证结果的正确性,自定义函数默认属性是不下推的,这会导致计算不下推,从而导致比较验证的性能问题。本文主要描述下函数在满足特征的前提下可以把函数属性定义为下推属性。
在展开介绍之前,我们先介绍一下DWS里面函数的几个属性
2. 易变属性
属性值 | 属性介绍 | 解释 | 实例 |
---|---|---|---|
IMMUTABLE | 在任何情况下同样的输入参数永远返回同样的结果 | 这类型函数在入参相同的时候,返回结果总是固定的,不受任何环境或者配置参数的影响。一般这类满足以下特征 1.函数的入参的数据解析不受任何配置参数影响 2.函数体内调用的函数的易变属性必须都是IMMUTABLE 3.函数内部不涉及表查询动作 |
` CREATE OR REPLACE FUNCTION public.isnumeric(text) RETURNS boolean LANGUAGE sql IMMUTABLE AS <math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mi>u</mi><mi>n</mi><mi>c</mi><mi>t</mi><mi>i</mi><mi>o</mi><mi>n</mi></mrow><annotation encoding="application/x-tex">function</annotation></semantics></math>function SELECT $1 ~ '^(([-+]?[0-9]+(.[0-9]+)?) |
STABLE | 在固定的配置下,在同一个查询中,对于同样的输入参数,函数返回的结果相 | 这类型函数在入参相同的时候,返回结果总是固定的。但是配置参数一旦变更,结果就可能发生变更。一般这类函数至少满足以下特征 1. 函数的入参的数据解析受配置参数影响,不同配置情况下,解析结果不一致 2. 函数体内调用的函数处理逻辑受配置参数影响,不同配置情况下,解析结果不一致 3. 函数体内不能调用的函数不能包含易变属性是VOLATILE的函数 4. 函数体内涉及的表查询只能是用户表,且必须是复制表;如果为其它分布表,则不能定义为stable |
-- 入参转化为时间类型受配置参数dateStyle的影响CREATE OR REPLACE FUNCTION public.datestr(text) RETURNS text LANGUAGE sql STABLE AS <math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mi>u</mi><mi>n</mi><mi>c</mi><mi>t</mi><mi>i</mi><mi>o</mi><mi>n</mi></mrow><annotation encoding="application/x-tex">function</annotation></semantics></math>function SELECT to_char($1::timestamp, 'YYYYMMDD') <math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mi>u</mi><mi>n</mi><mi>c</mi><mi>t</mi><mi>i</mi><mi>o</mi><mi>n</mi></mrow><annotation encoding="application/x-tex">function</annotation></semantics></math>function;-- 测试用例 postgres=# SET dateStyle = 'German, MDY'; SET postgres=# SELECT public.datestr('02.01.2021 21:23:40'); datestr ---------- 20210201 (1 row) postgres=# SET dateStyle = 'German, DMY'; SET postgres=# SELECT public.datestr('02.01.2021 21:23:40'); datestr ---------- 20210102 (1 row) -- 查询结果受表dim_student数据的影响 CREATE OR REPLACE FUNCTION public.fetchdesc(text) RETURNS text LANGUAGE sql STABLE AS <math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mi>u</mi><mi>n</mi><mi>c</mi><mi>t</mi><mi>i</mi><mi>o</mi><mi>n</mi></mrow><annotation encoding="application/x-tex">function</annotation></semantics></math>function SELECT info FROM dfm.dim_student WHERE id = <math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo separator="true">;</mo><mo><</mo><mi>b</mi><mi>r</mi><mi mathvariant="normal">/</mi><mo>></mo></mrow><annotation encoding="application/x-tex">1; <br /></annotation></semantics></math>1;<br/>function$; --测试用例 postgres=# CREATE TABLE dfm.dim_student(id text, info text) postgres-# DISTRIBUTE BY REPLICATION; CREATE TABLE postgres=# postgres=# INSERT INTO dfm.dim_student VALUES('001', 'v1'); INSERT 0 1 postgres=# select * from public.fetchdesc('001'); fetchdesc ----------- v1 (1 row) postgres=# TRUNCATE dfm.dim_student; TRUNCATE TABLE postgres=# select * from public.fetchdesc('001'); fetchdesc ----------- (1 row)` |
VOLATILE | 对于同样的输入参数,每次返回结果可能不通 | 函数默认值,不满足STABLE和IMMUTABLE属性的函数的易变属性都要定义为VOLATILE |
3. 下推属性
属性值 | 属性介绍 | 解释 |
---|---|---|
SHIPPALE | 函数可以下推到DN上执行 | 建议只有易变属性为STABLE和IMMUTABLE的函数才能定义为SHIPPALE属性 |
NOT SHIPPABLE | 函数不可以下推到DN上执行 | 函数下推属性默认值 |
4.自定义函数简单判断逻辑
需要关注字段funcdef_diagnosis输出为非NULL的记录
--输出列funcdef_diagnosis的取值有四个
--1. 输出为空
** 没有诊断出异常信息
--2. 输出为:ERROR: table operations in the stable/immutable function body
** 说明stable/immutable函数中可能出现了表操作动作(update|truncate|delete|insert|merge|create |drop| alter)
--3.输出为:NOTICE: the tableless operation function is determined not shippable
** 说明函数定义中没有表表操作,但是函数定义为不可下推
** 如果函数中没有表查询动作,并且不存在结果随机的函数,建议把函数定义为可下推的
--4.输出为:NOTICE: maybe table operations in the shippable function
** 说明可下推函数(proshippable = true 或者 provolatile= 'i')中可能存在查询表的动作
** 函数中如果有表查询动作,建议把函数定义为不下推
WITH funcdef AS( SELECT
rolname AS proowner,
proshippable,
provolatile,
lanname,
prosrc,
prosrc ~* '(update|truncate|delete|insert|merge)' AS contain_dml,
prosrc ~* '(create | drop | alter)' AS contain_ddl,
prosrc ilike '%select%from%' AS contain_select,
(pg_get_functiondef(p.oid)).definition AS functiondef
FROM pg_proc p
INNER JOIN pg_language l ON l.oid = p.prolang
INNER JOIN pg_roles r ON r.oid = p.proowner
WHERE p.oid >= 16384 -- 只检测自定义函数
AND lanname IN ('sql','plpgsql')--只检测SQL和plpgsql函数
)
SELECT
proowner,
proshippable,
provolatile,
lanname,
contain_dml,
contain_ddl,
contain_select,
CASE WHEN (contain_dml OR contain_ddl) THEN
CASE WHEN provolatile IN ('i', 's')
THEN 'ERROR: table operations in the stable/immutable function body'
END
WHEN contain_select = false THEN
CASE WHEN provolatile <> 'i' AND proshippable = false
THEN 'NOTICE: the tableless operation function is determined not shippable'
END
WHEN contain_select THEN
CASE WHEN proshippable = true OR provolatile= 'i'
THEN 'NOTICE: maybe table operations in the shippable function'
END
END AS funcdef_diagnosis,
functiondef
FROM funcdef
;
4. 总结
函数下推要首先满足以下
- 函数的易变属性为IMMUTABLE和STABLE
- 函数的下推属性设置为SHIPPALE
可以在函数定义的时候指定SHIPPALE属性,可以通过ALTER语句修改函数的下推属性
定义下推函数 | 修改函数属性为下推属性 |
---|---|
-- 入参转化为时间类型受配置参数dateStyle的影响 CREATE OR REPLACE FUNCTION public.datestr(text) RETURNS text LANGUAGE sql SHIPPABLE STABLE AS <math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mi>u</mi><mi>n</mi><mi>c</mi><mi>t</mi><mi>i</mi><mi>o</mi><mi>n</mi></mrow><annotation encoding="application/x-tex">function</annotation></semantics></math>function SELECT to_char($1::timestamp, 'YYYYMMDD') <math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mi>u</mi><mi>n</mi><mi>c</mi><mi>t</mi><mi>i</mi><mi>o</mi><mi>n</mi></mrow><annotation encoding="application/x-tex">function</annotation></semantics></math>function; |
ALTER FUNCTION public.datestr(text) SHIPPABLE; |
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)