Skip to content

No triggers — schedule, chain, or on-demand refresh

Watch tables are optional. Register with p_watch_tables => NULL (or omit the parameter) and no triggers are installed. The view then refreshes when a schedule fires, a chain dispatches it, or you call refresh_materialised_view_now().

When is this the right choice?

  • Bulk data loads — your ETL job loads 500,000 rows from a staging table. You do not want a trigger firing 500,000 times. Register the view with no watch tables and p_populate_if_empty => false (the view is still empty at registration time — you don't want it refreshed before the load runs); call refresh_materialised_view_now() once the load completes. See section 9.

  • Schedule-only views — the view only needs refreshing on a fixed cadence (nightly, weekly):

    SELECT pgauto_mv.register_mv(
        p_mv_name       => 'monthly_report',
        p_mv_schema     => 'finance',
        p_watch_tables  => NULL,
        p_schedule => ARRAY[pgrelay.on_dow('everyday', '02:00')]    -- the function only considers the first 3-letters of the scheduled day, so 'eve' = everyday, 'mon' = monday and so on. 'all' = 'eve'.
    );
    

  • Downstream aggregations — the view reads from another materialised view. Register it with no watch tables and chain it to its parent — it refreshes immediately after the parent does. See section 13.

  • Operator-controlled refreshes — the view is expensive and is only refreshed when an operator explicitly asks for it.