PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

मैं यह कैसे सुनिश्चित कर सकता हूं कि एक भौतिक दृश्य हमेशा अप टू डेट हो?

<ब्लॉककोट>

मुझे मटेरियलाइज्ड व्यू को रीफ्रेश करना होगा शामिल तालिकाओं में प्रत्येक परिवर्तन पर, है ना?

हां, PostgreSQL अपने आप इसे कभी भी स्वचालित रूप से कॉल नहीं करेगा, आपको इसे किसी तरह से करने की आवश्यकता है।

<ब्लॉककोट>

मुझे यह कैसे करना चाहिए?

इसे हासिल करने के कई तरीके। कुछ उदाहरण देने से पहले, ध्यान रखें कि सामग्री को ताज़ा करें कमांड एक्सेस एक्सक्लूसिव मोड में व्यू को ब्लॉक करता है, इसलिए जब यह काम कर रहा होता है, तो आप सेलेक्ट भी नहीं कर सकते। मेज पर।

हालांकि, यदि आप संस्करण 9.4 या नए संस्करण में हैं, तो आप इसे CONCURRENTLY दे सकते हैं विकल्प:

REFRESH MATERIALIZED VIEW CONCURRENTLY my_mv;

यह एक एक्सक्लूसिव लॉक प्राप्त करेगा, और ब्लॉक नहीं करेगा SELECT क्वेरी, लेकिन एक बड़ा ओवरहेड हो सकता है (डेटा की मात्रा पर निर्भर करता है, अगर कुछ पंक्तियां बदल गई हैं, तो यह तेज़ हो सकती है)। हालाँकि आप अभी भी दो REFRESH नहीं चला सकते हैं समवर्ती रूप से आदेश देता है।

मैन्युअल रूप से रीफ़्रेश करें

यह विचार करने का एक विकल्प है। विशेष रूप से डेटा लोडिंग या बैच अपडेट के मामलों में (उदाहरण के लिए एक प्रणाली जो लंबे समय के बाद केवल टन जानकारी/डेटा लोड करती है) डेटा को संशोधित या संसाधित करने के लिए अंत में संचालन करना आम बात है, इसलिए आप आसानी से एक <कोड शामिल कर सकते हैं>ताज़ा करें इसके अंत में संचालन।

रिफ्रेश ऑपरेशन शेड्यूल करना

पहला और व्यापक रूप से उपयोग किया जाने वाला विकल्प कुछ शेड्यूलिंग सिस्टम का उपयोग ताज़ा करने के लिए करना है, उदाहरण के लिए, आप क्रॉन जॉब में इस तरह को कॉन्फ़िगर कर सकते हैं:

*/30 * * * * psql -d your_database -c "REFRESH MATERIALIZED VIEW CONCURRENTLY my_mv"

और फिर आपका भौतिक दृश्य प्रत्येक 30 मिनट में ताज़ा हो जाएगा।

विचारों

यह विकल्प वास्तव में अच्छा है, विशेष रूप से CONCURRENTLY . के साथ विकल्प, लेकिन केवल तभी जब आप डेटा को 100% अप टू डेट हर समय स्वीकार कर सकते हैं। ध्यान रखें, कि CONCURRENTLY . के साथ या उसके बिना भी , रिफ्रेश कमांड को पूरी क्वेरी चलाने की आवश्यकता होती है, इसलिए आपको REFRESH शेड्यूल करने के समय पर विचार करने से पहले आंतरिक क्वेरी को चलाने के लिए आवश्यक समय निकालना होगा। ।

ट्रिगर के साथ रीफ़्रेश करना

दूसरा विकल्प है रिफ्रेश मैटेरियलाइज्ड व्यू . को कॉल करना एक ट्रिगर फ़ंक्शन में, इस तरह:

CREATE OR REPLACE FUNCTION tg_refresh_my_mv()
RETURNS trigger LANGUAGE plpgsql AS $$
BEGIN
    REFRESH MATERIALIZED VIEW CONCURRENTLY my_mv;
    RETURN NULL;
END;
$$;

फिर, किसी भी तालिका में जिसमें दृश्य में परिवर्तन शामिल हैं, आप यह करते हैं:

CREATE TRIGGER tg_refresh_my_mv AFTER INSERT OR UPDATE OR DELETE
ON table_name
FOR EACH STATEMENT EXECUTE PROCEDURE tg_refresh_my_mv();

विचारों

इसमें प्रदर्शन और समरूपता के लिए कुछ महत्वपूर्ण नुकसान हैं:

  1. किसी भी INSERT/UPDATE/DELETE ऑपरेशन को क्वेरी निष्पादित करनी होगी (यदि आप एमवी पर विचार कर रहे हैं तो यह धीमी गति से संभव है);
  2. यहां तक ​​कि समवर्ती के साथ भी , एक रीफ्रेश अभी भी एक दूसरे को ब्लॉक करता है, इसलिए शामिल टेबल पर कोई भी INSERT/UPDATE/DELETE क्रमबद्ध किया जाएगा।

केवल एक ही स्थिति मैं सोच सकता हूं कि एक अच्छा विचार यह है कि यदि परिवर्तन वास्तव में दुर्लभ हैं।

LISTEN/NOTIFY का उपयोग करके रीफ़्रेश करें

पिछले विकल्प के साथ समस्या यह है कि यह सिंक्रोनस है और प्रत्येक ऑपरेशन पर एक बड़ा ओवरहेड लगाता है। इसे सुधारने के लिए, आप पहले की तरह एक ट्रिगर का उपयोग कर सकते हैं, लेकिन वह केवल एक सूचित को कॉल करता है ऑपरेशन:

CREATE OR REPLACE FUNCTION tg_refresh_my_mv()
RETURNS trigger LANGUAGE plpgsql AS $$
BEGIN
    NOTIFY refresh_mv, 'my_mv';
    RETURN NULL;
END;
$$;

तो फिर आप एक ऐसा एप्लिकेशन बना सकते हैं जो कनेक्टेड रहे और LISTEN . का उपयोग करे कॉल करने की आवश्यकता की पहचान करने के लिए ऑपरेशन REFRESH . एक अच्छा प्रोजेक्ट जिसका उपयोग आप इसका परीक्षण करने के लिए कर सकते हैं वह है pgsidekick, इस प्रोजेक्ट के साथ आप LISTEN करने के लिए शेल स्क्रिप्ट का उपयोग कर सकते हैं , ताकि आप REFRESH . शेड्यूल कर सकें के रूप में:

pglisten --listen=refresh_mv --print0 | xargs -0 -n1 -I? psql -d your_database -c "REFRESH MATERIALIZED VIEW CONCURRENTLY ?;"

या pglater . का उपयोग करें (pgsidekick . के अंदर भी ) यह सुनिश्चित करने के लिए कि आप REFRESH . पर कॉल न करें अक्सर। उदाहरण के लिए, आप इसे REFRESH बनाने के लिए निम्न ट्रिगर का उपयोग कर सकते हैं , लेकिन 1 मिनट (60 सेकंड) के भीतर:

CREATE OR REPLACE FUNCTION tg_refresh_my_mv()
RETURNS trigger LANGUAGE plpgsql AS $$
BEGIN
    NOTIFY refresh_mv, '60 REFRESH MATERIALIZED VIEW CONCURRENLTY my_mv';
    RETURN NULL;
END;
$$;

तो यह REFRESH को कॉल नहीं करेगा 60 सेकंड से भी कम समय में, और यदि आप सूचित 60 सेकंड से भी कम समय में कई बार, REFRESH केवल एक बार ट्रिगर किया जाएगा।

विचारों

क्रॉन विकल्प के रूप में, यह भी तभी अच्छा है जब आप थोड़े पुराने डेटा के साथ नंगे हो सकते हैं, लेकिन इसका यह फायदा है कि REFRESH केवल तभी कॉल किया जाता है जब वास्तव में आवश्यकता होती है, इसलिए आपके पास कम ओवरहेड होता है, और डेटा को जरूरत पड़ने पर और अधिक अपडेट किया जाता है।

ओबीएस:मैंने वास्तव में अभी तक कोड और उदाहरणों की कोशिश नहीं की है, इसलिए अगर किसी को कोई गलती मिलती है, टाइपो या कोशिश करता है और काम करता है (या नहीं), तो कृपया मुझे बताएं।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. कोई रिकॉर्ड नहीं मिलने पर शून्य लौटाएं

  2. Postgres-XL 9.6 . में नया क्या है?

  3. विस्तार के साथ PostgreSQL में लॉगऑन (ओरेकल) ट्रिगर के बाद - login_hook

  4. Ubuntu पर pgAdmin का उपयोग करके Postgres को लोकलहोस्ट सर्वर से कैसे कनेक्ट करें?

  5. PostgreSQL, नुस्खा द्वारा सामग्री की गणना के लिए जटिल क्वेरी