抖一抖!原来函数还有稳不稳定的说法
函数的稳定性
函数稳定性参数的三种状态
- IMMUTABLE:函数在plan时执行且只执行一次。在 select 后面调用序列只会生成多个相同的值;在 where 后面调用序列只会生成多个相同的值
- STABLE:函数在execute时执行。在 select 后面调用序列会生成多个不同的值;在 where 后面调用序列只会生成多个相同的值
- VOLATILE:函数在execute时执行。在 select 后面调用序列会生成多个不同的值;在 where 后面调用序列会生成多个不同的值。默认值
| 函数稳定性参数 | 执行时刻 | SELECT后调用序列 | WHERE后调用 | |
|---|---|---|---|---|
| IMMUTABLE | PLAN | 生成多个相同的值 | 生成多个相同的值 | |
| STABLE | EXECUTE | 生成多个不同的值 | 生成多个相同的值 | |
| VOLATILE | EXECUTE | 生成多个不同的值 | 生成多个不同的值 | 默认值 |
稳定性:immutable > stable > volatile
⚠️注意:序列无法回滚
下面分别演示在事务里、在同一条SQL里和在where后调用这3种状态的不同表现
构造测试环境
-- 查看nextval的函数定义
10:10:42 pg14@testdb=# \sf nextval
CREATE OR REPLACE FUNCTION pg_catalog.nextval(regclass)
RETURNS bigint
LANGUAGE internal
STRICT
AS $function$nextval_oid$function$
-- 创建自定义测试函数test_nextval
CREATE OR REPLACE FUNCTION test_nextval(regclass)
RETURNS bigint
LANGUAGE internal
STRICT
AS $function$nextval_oid$function$;
-- 创建测试序列
create sequence test_sequence;

在事务里调用
行为一致,没有差别
alter function test_nextval(regclass) immutable;
-- 事务里调用
begin;
select test_nextval('test_sequence'),test_nextval('test_sequence');
rollback;
alter function test_nextval(regclass) stable;
alter function test_nextval(regclass) volatile;


同一条SQL里调用
指定 immutable 的函数执行计划的计划器在解析sql并执行的时不管有多少条记录,只会执行一次
alter function test_nextval(regclass) immutable;
-- 同一条SQL里调用
select test_nextval('test_sequence'::regclass) from generate_series(1,3);
alter function test_nextval(regclass) stable;
alter function test_nextval(regclass) volatile;

WHERE后调用
放在 WHERE 后调用,指定 immutable 或 stable 的函数只执行一次,默认的 volatile 会执行多次
select currval('test_sequence');
alter function test_nextval(regclass) immutable;
-- where后调用
select * from (select generate_series(1,5)) as temp where test_nextval('test_sequence')=17;
alter function test_nextval(regclass) stable;
alter function test_nextval(regclass) volatile;


「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




