2013-11-14 4 views
8

मैं एक पोस्टग्रेस्क्लु 9.3 डेटाबेस में डेटा का एक गुच्छा लोड कर रहा हूं और फिर मैं अद्यतन सामग्री पर निर्भर सभी भौतिक दृश्यों को रीफ्रेश करना चाहता हूं। क्या प्रत्येक दृश्य को देखने और उन्हें एक-एक करके रीफ्रेश करने के बजाय स्वचालित रूप से ऐसा करने का कोई तरीका है? मुझे पता है कि ओरेकल इसे आसानी से कर सकता है लेकिन मुझे PostgreSQL दस्तावेज के माध्यम से मिलकर कुछ भी नहीं मिला।पोस्टग्रेस्क्ल 9.3 में सभी भौतिक दृश्यों को एक बार में रीफ्रेश कैसे करें?

CREATE OR REPLACE FUNCTION RefreshAllMaterializedViews(schema_arg TEXT DEFAULT 'public') 
RETURNS INT AS $$ 
DECLARE 
    r RECORD; 
BEGIN 
    RAISE NOTICE 'Refreshing materialized view in schema %', schema_arg; 
    FOR r IN SELECT matviewname FROM pg_matviews WHERE schemaname = schema_arg 
    LOOP 
     RAISE NOTICE 'Refreshing %.%', schema_arg, r.matviewname; 
     EXECUTE 'REFRESH MATERIALIZED VIEW ' || schema_arg || '.' || r.matviewname; 
    END LOOP; 

    RETURN 1; 
END 
$$ LANGUAGE plpgsql; 

(GitHub पर: https://github.com/sorokine/RefreshAllMaterializedViews)

+1

pg_matviews जांचें, आपको आवश्यक सभी विचारों का चयन करें और रीफ्रेश करें। आप इसके लिए एक समारोह लिख सकते हैं। –

+0

मेरा खुद का फ़ंक्शन लिखने जैसा दिखता है वर्तमान संस्करण – srk

उत्तर

18

लगता PostgreSQL के वर्तमान संस्करण (9.3.1) इस तरह के सुविधा उपलब्ध नहीं है की तरह है, बजाय अपने खुद के समारोह लिखने के लिए पड़ा है

+1

के साथ एकमात्र विकल्प है [अब CONCURRELYLY]] (https://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.4#REFRESH_MATERIALIZED_VIEW_CONCURRENTLY) के समर्थन के साथ 9.4, टेबल लॉकिंग को रोकने के लिए इसका उपयोग करने के लिए आपकी रुचि होगी? –

+0

मैं इसे देखना चाहता हूं जैसे ही मुझे 9.4 इंस्टॉल पर हाथ मिल जाए। मुझे लगता है कि यह एक सुविधाजनक जोड़ होगा। – srk

+2

आज मैंने कोड को https://github.com/sorokine/RefreshAllMaterializedViews की मास्टर शाखा में खींच लिया है जो समवर्ती अद्यतन करता है। – srk

1

एक ही विधि, जोड़ा गया स्टैंडबाय चेक

CREATE OR REPLACE FUNCTION RefreshAllMaterializedViews(schema_arg TEXT DEFAULT 'public') 
RETURNS INT AS $$ 
DECLARE 
    r RECORD; 

BEGIN 
    RAISE NOTICE 'Refreshing materialized view in schema %', schema_arg; 
    if pg_is_in_recovery() then 
    return 1; 
    else 
    FOR r IN SELECT matviewname FROM pg_matviews WHERE schemaname = schema_arg 
    LOOP 
     RAISE NOTICE 'Refreshing %.%', schema_arg, r.matviewname; 
     EXECUTE 'REFRESH MATERIALIZED VIEW ' || schema_arg || '.' || r.matviewname; 
    END LOOP; 
    end if; 
    RETURN 1; 
END 
$$ LANGUAGE plpgsql; 
2

समान विधि, वैकल्पिक रूप से समवर्ती रूप से सभी स्कीमा पर चलाने के लिए विकल्प जोड़ा गया।

CREATE OR REPLACE FUNCTION RefreshAllMaterializedViews(_schema TEXT DEFAULT '*', _concurrently BOOLEAN DEFAULT false) 
RETURNS INT AS $$ 
    DECLARE 
    r RECORD; 
    BEGIN 
    RAISE NOTICE 'Refreshing materialized view(s) in % %', CASE WHEN _schema = '*' THEN ' all schemas' ELSE 'schema "'|| _schema || '"' END, CASE WHEN _concurrently THEN 'concurrently' ELSE '' END; 
    IF pg_is_in_recovery() THEN 
     RETURN 0; 
    ELSE  
     FOR r IN SELECT schemaname, matviewname FROM pg_matviews WHERE schemaname = _schema OR _schema = '*' 
     LOOP 
     RAISE NOTICE 'Refreshing %.%', r.schemaname, r.matviewname; 
     EXECUTE 'REFRESH MATERIALIZED VIEW ' || CASE WHEN _concurrently THEN 'CONCURRENTLY ' ELSE '' END || '"' || r.schemaname || '"."' || r.matviewname || '"'; 
     END LOOP; 
    END IF; 
    RETURN 1; 
    END 
$$ LANGUAGE plpgsql; 

मैं भी GitHub पर डाल दिया: https://github.com/frankhommers/RefreshAllMaterializedViews

1

टुकड़ा नीचे REFRESH MATERIALIZED VIEW CONCURRENTLY का उपयोग करता है जब एक UNIQUE सूचकांक उस दृश्य के लिए मौजूद है।

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; 

यह स्निपेट रीफ्रेश किए गए विचारों को सीमित करने के लिए स्कीमा नाम स्वीकार करता है।

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; 
संबंधित मुद्दे