函数的稳定性表现差异 IMMUTABLE | STABLE | VOLATILE
抖一抖!原来函数还有稳不稳定的说法
- 函数的稳定性
- 构造测试环境
- 在事务里调用
- 同一条SQL里调用
- WHERE后调用
函数的稳定性
函数稳定性参数的三种状态
- 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:42pg14@testdb=# \sf nextvalCREATEORREPLACEFUNCTIONpg_catalog.nextval(regclass)RETURNSbigintLANGUAGEinternal STRICTAS$function$nextval_oid$function$-- 创建自定义测试函数test_nextvalCREATEORREPLACEFUNCTIONtest_nextval(regclass)RETURNSbigintLANGUAGEinternal STRICTAS$function$nextval_oid$function$;-- 创建测试序列createsequence test_sequence;在事务里调用
行为一致,没有差别
alterfunctiontest_nextval(regclass)immutable;-- 事务里调用begin;selecttest_nextval('test_sequence'),test_nextval('test_sequence');rollback;alterfunctiontest_nextval(regclass)stable;alterfunctiontest_nextval(regclass)volatile;同一条SQL里调用
指定immutable的函数执行计划的计划器在解析sql并执行的时不管有多少条记录,只会执行一次
alterfunctiontest_nextval(regclass)immutable;-- 同一条SQL里调用selecttest_nextval('test_sequence'::regclass)fromgenerate_series(1,3);alterfunctiontest_nextval(regclass)stable;alterfunctiontest_nextval(regclass)volatile;WHERE后调用
放在 WHERE 后调用,指定immutable或stable的函数只执行一次,默认的volatile会执行多次
selectcurrval('test_sequence');alterfunctiontest_nextval(regclass)immutable;-- where后调用select*from(selectgenerate_series(1,5))astempwheretest_nextval('test_sequence')=17;alterfunctiontest_nextval(regclass)stable;alterfunctiontest_nextval(regclass)volatile;发现了一个前沿巨牛的宝藏人工智能学习网站,通俗易懂,风趣幽默,忍不住给大家分享一下。戳一下跳转到学习。
