此概念的接触是在做分区表的时候碰到的,分区表按时间字段分区,在查询时当where条件中时间为now()或者current_time()等时是无法查询的,即使进行格式转换也不行,只有是时间格式如‘2015-12-12’才能查询,在请教过以后说是函数形态的问题。搜索一篇文章介绍:
转自:http://blog.itpub.net/133735/viewspace-747843/
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 类型的函数,尽量不要声明。