How to refresh all materialized views in Postgresql 9.3 at once?

后端 未结 5 1628
青春惊慌失措
青春惊慌失措 2021-02-05 09:38

I am loading a bunch of data into a PostgresQL 9.3 database and then I want to refresh all materialized views that depend on the updated tables. Is there a way to do it automat

5条回答
  •  时光说笑
    2021-02-05 09:47

    The snippet below uses REFRESH MATERIALIZED VIEW CONCURRENTLY when a UNIQUE index exists for that view.

    CREATE OR REPLACE FUNCTION public.refresh_materialized_views()
      RETURNS void
    AS
    $BODY$
      DECLARE
          refresh_sql text;
        BEGIN
    
        WITH matviews AS (
           SELECT t.oid,
                  relname AS view_name,
                  nspname AS schema_name
             FROM pg_class t
             JOIN pg_catalog.pg_namespace n ON n.oid = t.relnamespace
            WHERE t.relkind = 'm'
              AND nspname NOT LIKE 'pg-%'
        ), unique_indexes AS (
         SELECT m.oid,
                view_name,
                schema_name
           FROM pg_class i,
                pg_index ix,
                matviews m
          WHERE ix.indisunique = true
            AND ix.indexrelid = i.oid
            AND ix.indrelid = m.oid
        ), refresh_concurrently AS (
          SELECT 'REFRESH MATERIALIZED VIEW CONCURRENTLY ' || quote_ident(schema_name) || '.' || quote_ident(view_name) AS sql
            FROM unique_indexes
        ), refresh AS (
          SELECT 'REFRESH MATERIALIZED VIEW ' || quote_ident(schema_name) || '.' || quote_ident(view_name) AS sql
            FROM matviews
           WHERE oid != all (SELECT oid FROM unique_indexes)
        ), sql AS (
          SELECT sql FROM refresh_concurrently
          UNION ALL
          SELECT sql FROM refresh
        )
    
        SELECT string_agg(sql, E';\n') || E';\n' FROM sql INTO refresh_sql;
    
        EXECUTE refresh_sql;
    
        END;
    $BODY$
    LANGUAGE plpgsql VOLATILE;
    

    This snippet accepts a schema name to limit the views that are refreshed.

    CREATE OR REPLACE FUNCTION public.refresh_materialized_views(_schema text)
      RETURNS void
    AS
    $BODY$
      DECLARE
          refresh_sql text;
        BEGIN
    
        WITH matviews AS (
           SELECT t.oid,
                  relname AS view_name,
                  nspname AS schema_name
             FROM pg_class t
             JOIN pg_catalog.pg_namespace n ON n.oid = t.relnamespace
            WHERE t.relkind = 'm'
              AND nspname NOT LIKE 'pg-%'
              AND nspname = _schema
        ), unique_indexes AS (
         SELECT m.oid,
                view_name,
                schema_name
           FROM pg_class i,
                pg_index ix,
                matviews m
          WHERE ix.indisunique = true
            AND ix.indexrelid = i.oid
            AND ix.indrelid = m.oid
        ), refresh_concurrently AS (
          SELECT 'REFRESH MATERIALIZED VIEW CONCURRENTLY ' || quote_ident(schema_name) || '.' || quote_ident(view_name) AS sql
            FROM unique_indexes
        ), refresh AS (
          SELECT 'REFRESH MATERIALIZED VIEW ' || quote_ident(schema_name) || '.' || quote_ident(view_name) AS sql
            FROM matviews
           WHERE oid != all (SELECT oid FROM unique_indexes)
        ), sql AS (
          SELECT sql FROM refresh_concurrently
          UNION ALL
          SELECT sql FROM refresh
        )
    
        SELECT string_agg(sql, E';\n') || E';\n' FROM sql INTO refresh_sql;
    
        EXECUTE refresh_sql;
    
        END;
    $BODY$
    LANGUAGE plpgsql VOLATILE;
    

提交回复
热议问题