Skip to content

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.:

  1. 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)

  1. 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