PG 函式的易變性(Function Volatility Categories)

babyyellow發表於2012-10-29
pg 函式的valatility 有3個屬性:

1) volatile :   這種型別的函式可以做任何事情,包括修改資料庫,在對同一個引數連續多次呼叫,返回的只值可能是不一樣的。
                  pg的最佳化器不會對這類函式做任何假設,對於資料庫裡的每一行都針對這個函式重新計算。

2) stable :  這種型別的函式不能修改資料庫,在同一個語句返回的所有的行中,相同的引數對應的返回值是相同的。
                 pg最佳化器可以針對這類函式做最佳化,對於該函式的多次求值,轉化為只求值一次。  實際上,如果表示式中包含了這類函式,.
               是可以利用到索引掃描。這其實就可以顛覆我們在oracle 或者mysql 上的認識,函式列上的計算不能走索引。

3) IMMUTABLE :  這種型別的函式,認為對相同引數的返回值永遠都一樣的。  
                     pg最佳化器可以對這類函式針對常量的引數預先求職。例如select * from tab where  x=2+2 ; 可以計算為 where =4;


對於有副作用的函式必須申明為volatile 。 這類函式是無法最佳化的,如果把實際上stable 型別的函式,宣告為volatile ,他的行為也會改變

一個特例是 current_timestamp 族的函式,這類函式在同一個事務裡返回的值是一樣的,這裡函式是stable 型別的。

stable 與 IMMUTABLE  型別的函式在大部分情況向,可以認為是有相同的行為,在命令列單句執行的sql中,這兩類函式的行為是一致的,
如果在預編譯(prepared-statment)語句中,是不一樣的。 在子查詢中,如果cache 了執行計劃, 對於immutable 型別的函式可能會返回錯誤的結果。



另一個問題,3種型別的函式的資料可見性問題:

volatile 型別的函式,在每次執行的時候,都會重新整理當前的資料檢視(mvcc)
stable 與immutable 型別的行數,在語句開始執行的時候,就建立了資料快照,直到執行結束。


volatile 型別的函式是不能做為函式索引的表示式的,stable 型別的可以。

如果函式里的語句都是select  類的查詢語句,函式宣告為那種型別一般是沒有什麼影響的。這個情況我們應該儘可能的宣告為stable 型別。

immutable 型別的函式,儘量不要宣告。











來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/133735/viewspace-747843/,如需轉載,請註明出處,否則將追究法律責任。

相關文章