これは非常に興味深い質問であり、PostgreSQL メーリング リストで取り上げることをお勧めします。
簡単に言えば、これらは呼び出した関数ではなく、実行内容によって強制されるということです。
これにより、かなり興味深いことができます。たとえば、クエリごとに 1 つの乱数を作成する値が必要だとします。
create function rand_im() returns double precision language sql immutable as
$$ select random(); $$;
これで不変の乱数関数ができました。クエリ プランが形成される前に発生する単一の呼び出しに最適化できるため、インデックスが役立つかどうかを判断するために使用できます。
chris=# explain analyse select * from profile_matches where id > (4 * rand_im());
QUERY PLAN
--------------------------------------------------------------------------------
-----------------------------
Seq Scan on profile_matches (cost=0.00..39.10 rows=647 width=12) (actual time=
0.009..0.010 rows=1 loops=1)
Filter: ((id)::double precision > 3.24490546248853::double precision)
Total runtime: 0.022 ms
(3 rows)
したがって、ここには明らかに揮発性の関数を呼び出す「不変」があり、これは実際に便利です。これにより、フラット化される関数を作成でき、クエリに正確に 1 つの値を提供できるからです。
さて、他のリンクによると、揮発性関数を呼び出す安定した関数に関して何が起こるか本当にわかりません。私が知る限り、これは単なる最適化であり、保護は最小限ですが、db の副作用が常に許可されるとは限りません。
さらに、考慮すべき簡単なことは、関数がプランナーに不透明であり、すべての手続き型言語でこの種のことを防ぐことはできないということです。不変であるとラベル付けされる可能性があるが、クエリを実行できる Java 関数を使用できると考えてください (これはおそらく良いことではありません)。したがって、これは明らかな間違いのように思えるかもしれませんが、実際には潜在的に役立つものです。