Aviso: Este artigo ainda é um rascunho!
Quando as funções são definidas no PosgreSQL sem a opção IMMUTABLE estas não podem ser utilizados como valores para índices.
Por isso se utilizar uma função assim definida para definir um campo que seja indice de uma tabela a mesma será lida sequencialmente (seq scan/ FULL).
Por tanto é interessante que as funçoes que dados uma entrada tem para um select a mesma saída é importante utilizar esta opção.
Exemplo de plano de execução com TO_DATE com IMMUTABLE:
totali=# EXPLAIN totali-# SELECT * totali-# FROM TT_VEN totali-# WHERE DATHOR=TO_DATE('01/01/2004','DD/MM/YYYY');
QUERY PLAN
Index Scan using i_lc_ven_dathor on tt_ven (cost=0.00..5.81 rows=1 width=602) Index Cond: (dathor = '2004-01-01 00:00:00'::timestamp without time zone)
(2 rows)
Note que utilizou indice corretamente.
Exemplo de plano de execução com TO_DATE sem IMMUTABLE:
totali=# EXPLAIN totali-# SELECT * totali-# FROM TT_VEN totali-# WHERE DATHOR=TO_DATE('01/01/2004','DD/MM/YYYY');
QUERY PLAN
Seq Scan on tt_ven (cost=0.00..204.59 rows=1 width=602)
Filter: (dathor = to_date('01/01/2004'::text, 'DD/MM/YYYY'::text))
(2 rows)
Obs.: Somente deve-se atentar para o seguintes resultados caso a função retorne valores diferentes para uma mesma entrada:
Ex.:
- Função definida normalmente:
CREATE OR REPLACE FUNCTION testeRand () RETURNS integer AS ' DECLARE retorno integer; begin select proximocodigo(TT_GRA,001) into retorno; return retorno; END;
' language 'plpgsql';
totali=> select testeRand () from td_fil; testerand
11040
11041
11042
11043
(4 rows)
- Função definida com IMMUTABLE:
CREATE OR REPLACE FUNCTION testeRand () RETURNS integer AS ' DECLARE retorno integer; begin select proximocodigo(TT_GRA,001) into retorno; return retorno; END;
' language 'plpgsql' STRICT IMMUTABLE;
totali=> select testeRand () from td_fil; testerand
11039
11039
11039
11039 (4 rows)
Para criar uma função com IMMUTABLE basta utilizar a macro ENDFUNCTION_IMMUTABLE ao invés de ENDFUNCTION