こんにちはパフォーマンス改善SEの松崎です。
今回はPostgreSQLの共通テーブル式 WITH句について掲載させていただきます。
WITH句はクエリの再利用によるパフォーマンスの改善や可読性の高さで使用している方が多いと思います。
実はあまり知られていないですがPostgreSQL12からWITH句の内部動作について変更がありました。
PostgreSQL11などではWITH句で定義されているクエリを必ずメモリに仮想テーブルを展開(マテリアライズ化)する動作となっていました。
PostgreSQL12からはWITH句で定義されているクエリが複数回使用されている場合はマテリアライズ化、1回のみの使用の場合はメインクエリから実テーブルを直接参照するようになりました。
1回のみの使用の場合はマテリアライズ化が不要になりwork_memの消費を抑えたりインデックが適切に使用される可能性が高いなどのメリットがあります。
しかし大量データのテーブルから一時抽出してパフォーマンスを改善などでWITH句を使用していた場合は直接テーブルを参照することにより大幅な性能劣化となる可能性があります。
この場合は
WITH tmp AS MATERIALIZED (クエリ)〜
のようにMATERIALIZEDキーワード記載することでマテリアライズが行われPostgreSQL11と同様の動作となります。
PostgreSQLのアップデートによりWITH句のクエリが遅くなった場合になどで是非試してみてください。