タイムゾーン フィールドを使用してタイムスタンプで範囲分割されたテーブルがあります。次の where 条件により、プランナーがパーティション内のすべての「子」テーブルをクエリするようになったことに非常に驚きました。
WHERE reading_time > (now() - '72:00:00'::interval)
私が学んだように、プランナーは実行時に now() がどうなるかを知らないため、すべての子テーブルを照会するプランを生成します。それは理解できますが、そもそもパーティションを設定する目的に反します! reading_time > '2018-03-31' を発行すると、これらの条件を満たすデータを含むテーブルのインデックス スキャンのみが実行されます。
次の関数を作成するとどうなりますか
CREATE OR REPLACE FUNCTION public.last_72hours(in_time timestamp with time zone)
Select * from precip where reading_time > (in_time - '72:00:00'::interval)
--the function will then do work on the returned rows
END;
次に、関数を呼び出すことができます
SELECT last_72hours(now())
now() はいつ評価されますか? 言い換えれば、リテラル時間値 (例: 2018-03-31 1:01:01+5) が関数に渡されますか? それがリテラル値の場合、Postgres は適切な子テーブルのみをクエリしますよね? しかし、関数内で now() を評価している場合は、すべての子テーブルのインデックスをスキャンする計画に戻ります。プランナーが関数内で何をしているのかを確認するのは簡単ではないようです。あれは正しいですか?