循序渐进丨MogDB / openGauss 的三种函数稳定性关键字


云和恩墨
云和恩墨 2024-02-29 09:30:43 49168
分类专栏: 资讯

一、Oracle 中类似的函数稳定性关键字(DETERMINISTIC)

在 Oracle 里,function有着一个DETERMINISTIC参数,它表示一个函数在输入不变的情况下输出是否确定,只要输入的参数一样,返回的结果一定是一样的,以保证函数对于任何输入总是完全相同的方式处理参数。Oracle 的内置函数UPPER、TRUNC等都是DETERMINISTIC函数。具体例子如下:

 

----带DETERMINISTIC的现象create or replace function f_t(i_p int) return number DETERMINISTIC is      i_rtn number;    begin      i_rtn := i_p * dbms_random.value(1,10);      return i_rtn;    end;    /
select LEVEL,f_t(1) FROM DUAL CONNECT BY LEVEL<=10;
----不带DETERMINISTIC的现象
create or replace function f_t(i_p int) return number is i_rtn number; begin i_rtn := i_p * dbms_random.value(1,10); return i_rtn; end; /
select LEVEL,f_t(1) FROM DUAL CONNECT BY LEVEL<=10;

图片

可以看到,带了DETERMINISTIC参数的,多次执行的结果都是一样的,能保证函数的稳定性。

二、MogDB / openGauss 的三种函数稳定性状态

MogDB 数据库的函数虽然没有DETERMINISTIC关键字,但是函数也有着类似的三种状态的关键字,分别是IMMUTABLE、STABLE和VOLATILE。合理使用这三种不同的状态可以显著改善函数性能。
在数据库里使用\d create function也可以看到这三种状态的关键字提示:

图片

01

IMMUTABLE(非常稳定)

 

任何时候调用,只要函数的参数不变结果就不变。纯函数,执行结果可能会在规划时被预求值并缓存。
允许优化器在一个查询用常量参数调用该函数时,提前计算该函数。
整数加法操作符底层的函数其实就是被被标记为IMMUTABLE的。
表示该函数不能修改数据库,并且对于给定的参数值总是会返回相同的值。也就是说,它不会做数据库查找或者使用没有在其参数列表中直接出现的信息。IMMUTABLE和STABLE非常类似,但是IMMUTABLE是指在任何情况下,只要参数一致,结果就一致。

02

STABLE(稳定)

 

在一个事务中调用时,只要函数的参数不变结果就不变。
STABLE函数不能修改数据库状态,但是对于相同的参数值,它在一次表扫描中将返回相同的结果。因而优化器可以将相同参数的多次调用优化成一次调用。在索引扫描条件中允许使用STABLE函数。
在大多数情况下使用这个状态。在单个表扫描中,对相同的参数值返回相同的结果,但结果将通过SQL语句进行更改,最后的输出结果取决于数据库查找或参数值。
current_timestamp系列函数是 STABLE; 值在执行中不会改变。
IMMUTABLE和STABLE很像,显著的区别是优化器对IMMUTABLE和STABLE函数的处理上,IMMUTABLE函数在优化器生成执行计划时会将函数结果替换函数,也就是函数不在输出的执行计划中,取而代之的是一个结果常量。STABLE函数则不会如此,执行计划里以函数输出。
IMMUTABLE和STABLE在调用次数上的明显区别可以用如下的测试验证出来:

 

CREATE OR REPLACE FUNCTION func_out_num() RETURNS INTEGER AS$$BEGINRAISE NOTICE 'Invoke the func.';RETURN 6;END;$$ LANGUAGE PLPGSQL STABLE;

select func_out_num() from generate_series(1,10);alter function func_out_num() immutable;select func_out_num() from generate_series(1,10);

图片

在本例中,当使用STABLE关键字的时候,会按照调用10次函数,而当使用IMMUTABLE关键字时,它会被优化为一次调用。
除此之外,把函数内容放到结果集部分,两种状态的差异也很大,如下测试可以看出:

 

MogDB=# create table test_stable (id int, info text);  CREATE TABLEMogDB=# insert into test_stable select generate_series(1,100000),random()::text;  INSERT 0 1000MogDB=# create index idx_test_a on test(id);  CREATE INDEX
创建如下函数:

 

create or replace function func_stable() returns numeric as $$  declare  begin    return 2;  end;  $$ language plpgsql stable; 

图片

使用如下语句可以进行验证两种方式的执行计划时间明显不同:
  •  
explain analyze select func_stable() from test_stable; 

图片

因此,在事务中参数一致则结果一致,且只关注函数的最终结果可以标记为IMMUTABLE,因为它调用函数的次数少,固化了函数的结果,执行计划的代价较小。但是一般还是建议使用STABLE,因为它会老老实实地去执行函数,而不是只取一个固化的结果。

03

VOLATILE(不稳定)

 

默认为VOLATILE。表示该函数的值在一次表扫描中都有可能改变,因此不能做优化。
VOLATILE函数可以做任何事情,包括修改数据库状态。在连续调用时即使使用相同的参数,也可能会返回不同的结果。优化器不会优化掉此类函数,每次调用都会重新求值。
在这种意义上,相对较少的数据库函数是不稳定的。例如: random(), currval(), timeofday()。任何具有副作用的函数都不稳定的,即使其结果是可预测的。例如: setval()。
只有函数声明了VOLATILE状态才可以进行update操作。
具体的验证如下所示:

 

MogDB=# create table test_volatile (id int, info text);  CREATE TABLEMogDB=# insert into test_volatile select generate_series(1,1000),random()::text;  INSERT 0 1000MogDB=# create index idx_test on test(id);  CREATE INDEX
然后建立测试的函数:

 

create or replace function func_volatile(ida int) returns text as $$  declare    result text;  begin     update test_volatile set info='xiaoguaishou' where id=ida returning info into result;    return result;  end;$$ language plpgsql volatile;  
可以看到测试结果:

图片

图片

作者简介

/ Author Introduction

 

阎书利 / 云和恩墨PG技术顾问

PostgreSQL ACE,《快速掌握 PostgreSQL 版本新特性》一书副主编,中国PG分会认证讲师,PGfans 2021年度MVP,Gauss松鼠会2021年度优秀会员,拥有PGCM、OCP(MySQL)等十多项数据库认证,目前主要从事于 PostgreSQL、openGauss / MogDB 的运维以及去O工作。

图片
图片

数据驱动,成就未来,云和恩墨,不负所托!


云和恩墨创立于2011年,以“数据驱动,成就未来”为使命,是智能的数据技术提供商。我们致力于将数据技术带给每个行业、每个组织、每个人,构建数据驱动的智能未来。

云和恩墨在数据承载(分布式存储、数据持续保护)、管理(数据库基础软件、数据库云管平台、数据技术服务)、加工(应用开发质量管控、数据模型管控、数字化转型咨询)和应用(数据服务化管理平台、数据智能分析处理、隐私计算)等领域为各个组织提供可信赖的产品、服务和解决方案,围绕用户需求,持续为客户创造价值,激发数据潜能,为成就未来敏捷高效的数字世界而不懈努力。

图片

网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。

本文链接:https://www.xckfsq.com/news/show.html?id=51803
赞同 1
评论 0 条
云和恩墨L3
粉丝 0 发表 25 + 关注 私信
上周热门
如何使用 StarRocks 管理和优化数据湖中的数据?  2959
【软件正版化】软件正版化工作要点  2878
统信UOS试玩黑神话:悟空  2843
信刻光盘安全隔离与信息交换系统  2737
镜舟科技与中启乘数科技达成战略合作,共筑数据服务新生态  1270
grub引导程序无法找到指定设备和分区  1235
华为全联接大会2024丨软通动力分论坛精彩议程抢先看!  165
点击报名 | 京东2025校招进校行程预告  164
2024海洋能源产业融合发展论坛暨博览会同期活动-海洋能源与数字化智能化论坛成功举办  163
华为纯血鸿蒙正式版9月底见!但Mate 70的内情还得接着挖...  159
本周热议
我的信创开放社区兼职赚钱历程 40
今天你签到了吗? 27
信创开放社区邀请他人注册的具体步骤如下 15
如何玩转信创开放社区—从小白进阶到专家 15
方德桌面操作系统 14
我有15积分有什么用? 13
用抖音玩法闯信创开放社区——用平台宣传企业产品服务 13
如何让你先人一步获得悬赏问题信息?(创作者必看) 12
2024中国信创产业发展大会暨中国信息科技创新与应用博览会 9
中央国家机关政府采购中心:应当将CPU、操作系统符合安全可靠测评要求纳入采购需求 8

加入交流群

请使用微信扫一扫!