天天看点

Postgres —— IMMUTABLE | STABLE | VOLATILE 案例(1)

作者:瀚高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都会执行一次。

           

继续阅读