はGenerating Random Data Via SQL彼は5つのランダムな文字列を生成するには、次のコードを使用していました。私が削除したとき、結果はまったく同じ5つの文字列に変更されました。つまり、Postgresは外側のselect式(結果)をキャッシュしました!PostgreSQLの揮発性表現やサブクエリブルースMomjianのブログ記事で
私は式キャッシングがPostgresでどのように機能しているのかわかりませんでした。 the documentationによると、random()関数はVOLATILEとマークされているので、どの表現もそれに依存すると予想されます。
どのようにして式キャッシュがPostgresで動作しますか?それはどこに文書化されていますか?なぜ 'b * 0'はrandom()がキャッシュしなかったキャッシュを無効にしたのですか?
更新:
問題を研究するために、私は())ランダムと同じ位置/レベル(であることを呼び出して、床の内部に 'B * 0' に移動:
...
SELECT chr(ascii('a') + floor(random() * 26 + b * 0)::integer)
FROM generate_series(1, 40) as s(f)
...
結果まだキャッシュされていません。異なる文字列。
アップデート:もう一つの例の問題を示すために
create sequence seq_test;
SELECT (SELECT nextval('seq_test')) FROM generate_series(1,5);
?column?
----------
1
1
1
1
1
(5 rows)
したがって、プランナは、それが依存していなくても(正確には揮発性であるにもかかわらず)各行 'f'の内部式を評価しますが、外側の式は行に依存しない限り1回評価されます。揮発性の値は、それに基づいて何らかの結果をもたらすべきではありませんか?行の依存性と同じように。 –
式のボラティリティにより、インライン化は中止されますが、サブセレクトが相関関係にあるかどうかに基づいてプランナがクエリプランをどのように配置するかには影響しません。 – araqnid
外部クエリの行変数に依存しない限り、サブクエリはSTABLEとみなされます。それは私のバグのように見えます。私は、揮発性の表現が任意の式やサブクエリに対してボラティリティのウイルス効果を持つことを期待します。 InitPlanは最適化であり、結果を変更すべきではありません。 –