作者:瀚高PG实验室 (Highgo PG Lab)-狮子歌歌
1.在postgres里,函数有三个状态,这三个状态跟函数的本身有关。
2.这些状态被Postgres执行计划的优化器拿来用,如果优化器看到你这个函数是超级稳定的状态,比如说 immutable,那么优化器对于同样的参数传入(在一个sql里面),
即使你扫描了多行,我也只会处理一遍,也就是说 immutable 类似于常量,对于同样的参数传入,只执行一遍,大大简化了运算量。
IMMUTABLE : 最稳定
STABLE :第二稳定
VOLATILE :最不稳定 :即使你传入参数是一样的,多次调用输出的结果也不一样。比如 select now();
- 对于状态为VOLATILE的函数来说,函数多次调用,输出的结果是不一样的。
postgres=# select now();
now
-------------------------------
2017-06-07 05:47:08.937961+08
(1 row)
postgres=# select now();
now
-------------------------------
2017-06-07 05:47:09.703899+08
(1 row)
postgres=# select now();
now
------------------------------
2017-06-07 05:47:10.44367+08
(1 row)
postgres=# create sequence seq; //创建一个序列
CREATE SEQUENCE
postgres=# select provolatile from pg_proc where proname='nextval'; //查询nextval函数当前所属的状态
provolatile
-------------
v //v 表示 VOLATILE ,即最不稳定的状态。
(1 row)
VOLATILE状态意味着:
无论在一个事务里,还是在一个sql里,netval的值一直是不同的。
举例:
//在一个事务里:
postgres=# begin;
BEGIN
postgres=# select nextval('seq');
nextval
---------
1
(1 row)
postgres=# select nextval('seq');
nextval
---------
2
(1 row)
postgres=# select nextval('seq');
nextval
---------
3
(1 row)
postgres=# select nextval('seq');
nextval
---------
4
(1 row)
postgres=# end;
// 在同一条语句里:
postgres=# select nextval('seq') from t;
nextval
---------
40
41
42
43
(4 rows)
postgres=# select nextval('seq') from t;
nextval
---------
44
45
46
47
(4 rows)
postgres=# select nextval('seq'::regclass) from generate_series(1,3);
nextval
---------
54
55
56
(3 rows)
可以看出来,结果都是不一样的,也就是说每次调用nextval,nextval都会执行一次。