函数的稳定性
函数稳定性参数的三种状态
- 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;



3963

被折叠的 条评论
为什么被折叠?



