天天看點

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都會執行一次。

           

繼續閱讀