PostgreSQL: स्मृति में बल डेटा


32

क्या PostgreSQL को किसी विशिष्ट तालिका को मेमोरी में लोड करने के लिए मजबूर करने के लिए एक व्यवस्थित तरीका है, या कम से कम इसे डिस्क से पढ़ें ताकि यह सिस्टम द्वारा कैश हो जाए?

जवाबों:


25

आप मेलिंग सूचियों में से किसी एक विषय में इंटरस्टेड हो सकते हैं , यह टॉम लेन (कोर देव) द्वारा उत्तर दिया गया है:

[..] लेकिन मेरी राय यह है कि जो लोग सोचते हैं कि वे LRU कैशिंग एल्गोरिथ्म की तुलना में अधिक स्मार्ट हैं, आमतौर पर गलत हैं। यदि तालिका वह सब है जो भारी रूप से उपयोग की जाती है, तो यह ठीक स्मृति में रहेगी। यदि यह LRU एल्गोरिथम के अनुसार मेमोरी में रहने के लिए पर्याप्त रूप से पर्याप्त रूप से उपयोग नहीं किया जाता है, तो शायद मेमोरी स्पेस वास्तव में कुछ और पर खर्च किया जाना चाहिए। [..]

आप SO प्रश्न में इंटरसेस्टेड भी हो सकते हैं: https://stackoverflow.com/questions/486154/postgresql-temporary-tables और शायद अधिक उपयुक्त https://stackoverflow.com/questions/40x6/need-to-load-the आज़ाद-PostgreSQL-डेटाबेस-में-राम


1
+1 वही विचार अन्य RDBMS पर भी लागू होता है।
gbn

25
हां और ना। हम कुछ Oracle तालिकाओं को स्मृति में बंद कर देते हैं क्योंकि हम जानते हैं कि उनका उपयोग अक्सर नहीं किया जा सकता है, लेकिन जिस स्थिति में उनका उपयोग किया जाता है, विलंबता एक हत्यारा होगा। डीबी को हमेशा डीबीए फाइनल कहना चाहिए (एक अन्य उदाहरण क्वेरी ऑप्टिमाइज़र को संकेत दे रहा है)।
गयुस

35

9.4 के बाद के अंत में ओएस या डेटाबेस बफर कैश (आपकी पसंद पर) में संबंधों से डेटा लोड करने के लिए एक एक्सटेंशन जोड़ा गया:

pg_prewarm

यह पूर्ण ऑपरेटिंग प्रदर्शन को और अधिक तेज़ी से पहुंचने देता है।

अपने डेटाबेस में एक बार चलाएं ( यहां विस्तृत निर्देश ):

CREATE EXTENSION pg_prewarm;

फिर किसी भी दिए गए रिश्ते को पहले से लोड करना सरल है। मूल उदाहरण:

SELECT pg_prewarm('my_tbl');

my_tblखोज पथ में नामित पहली तालिका को ढूँढता है और उसे पोस्टग्रेज बफर कैश में लोड करता है

या:

SELECT pg_prewarm('my_schema.my_tbl', 'prefetch');

prefetchऑपरेटिंग सिस्टम के लिए एसिंक्रोनस प्रीफ़ैच अनुरोध जारी करता है, अगर यह समर्थित है, या अन्यथा एक त्रुटि फेंकता है। read ब्लॉकों की अनुरोधित सीमा को पढ़ता है; इसके विपरीत prefetch, यह समकालिक और सभी प्लेटफार्मों और बिल्ड पर समर्थित है, लेकिन धीमा हो सकता है। bufferडेटाबेस बफ़र कैश में ब्लॉक की अनुरोधित सीमा को पढ़ता है।

डिफ़ॉल्ट है buffer, जिसका सबसे बड़ा प्रभाव (उच्च लागत, सर्वोत्तम प्रभाव) है।

अधिक विवरण के लिए मैनुअल पढ़ें , उद्धरण वहां से हैं।
डीपेज़ ने इसके बारे में भी ब्लॉग किया


4

सामान्य स्थिति में यदि आपके पास पर्याप्त रैम है तो आप आमतौर पर डेटाबेस सेवा पर भरोसा कर सकते हैं कि आप नियमित रूप से रैम में उपयोग की जाने वाली चीजों को रखने का एक अच्छा काम कर सकते हैं। कुछ सिस्टम आपको संकेत देते हैं कि तालिका को हमेशा रैम में रखा जाना चाहिए (जो कि छोटे-छोटे तालिकाओं के लिए उपयोगी होता है जो अक्सर उपयोग नहीं किए जाते हैं लेकिन जब उनका उपयोग किया जाता है तो यह महत्वपूर्ण है कि वे जितनी जल्दी हो सके जवाब दें) लेकिन अगर pgsql में ऐसी तालिका संकेत है आपको उनका उपयोग करने के बारे में बहुत सावधानी बरतने की आवश्यकता है क्योंकि आप कुछ और भी कैशिंग के लिए उपलब्ध स्मृति की मात्रा को कम कर रहे हैं ताकि आप अपने आवेदन को धीमा कर सकें।

यदि आप स्टार्टअप पर डेटाबेस के पेज कैश को प्राइम करने के लिए देख रहे हैं (उदाहरण के लिए रिबूट या अन्य रखरखाव ऑपरेशन के बाद जो DB को सब कुछ भूल जाता है जो कि कैश किया गया है) तो एक स्क्रिप्ट लिखें जो निम्न कार्य करता है:

SELECT * FROM <table>
SELECT <primary key fields> FROM <table> ORDER BY <primary key fields>
SELECT <indexed fields> FROM <table> ORDER BY <indexed fields>

(प्रत्येक इंडेक्स, या कोर्स के लिए दोहराया गया अंतिम चरण, और दाएं क्रम में ORDER BY क्लॉज में फ़ील्ड रखने के लिए सावधान रहें)

ऊपर चलाने के बाद हर डेटा और इंडेक्स पेज को पढ़ा जाना चाहिए और इसलिए रैम पेज कैश में होगा (कम से कम समय के लिए)। हमारे पास हमारे एप्लिकेशन डेटाबेस के लिए इस तरह की स्क्रिप्ट हैं, जो रिबूट के बाद चलाए जाते हैं ताकि सिस्टम में प्रवेश करने वाले पहले उपयोगकर्ता धीमी प्रतिक्रिया का अनुभव न करें। आप किसी भी तरह के स्क्रिप्ट हाथ लेखन, बजाय db परिभाषा टेबल स्कैनिंग (तरह से बेहतर कर रहे हैं sys.objects/ sys.indexes/ sys.columnsMSSQL में), तो आप चुनिंदा अनुक्रमित है कि सबसे अधिक स्कैनिंग के बजाय इस्तेमाल कर रहे हैं स्कैन कर सकते हैं सब कुछ जो लंबा समय लगेगा।


3
यह कम से कम PostgreSQL पर काम नहीं करेगा। पूरे बफर कैश का उपयोग करने से रोकने के लिए अनुक्रमिक स्कैन के लिए साझा बफ़र्स से एक छोटी (256KB) रिंग बफर आवंटित की जाती है। जानकारी के लिए github.com/postgres/postgres/blob/master/src/backend/storage/… देखें । आप एक बड़ी तालिका से एक SELECT * कर के इसे सत्यापित कर सकते हैं फिर pg_buffercache तालिका (pg_buffercache एक्सटेंशन से) देख रहे हैं।
hbn

@hbn हैलो वहाँ है, लेकिन इस बचत धागे में इस साथी आदमी का कहना है कि यह काम करता है - dba.stackexchange.com/a/36165/55752
scythargon

@ कैशथोरगन यह ओएस कैश में समाप्त हो सकता है, इसे पोस्टग्रेक्यूएल बफर कैश में नहीं मिलेगा। यदि आपने मुझ पर विश्वास नहीं किया तो मैंने जो भी ऊपर सुझाया था, उसे आज़माएँ।
एचबीएन

9.5 के पोस्टग्रैज में, मैंने कोशिश की SELECT * FROM schema.tableऔर देखा कि यह पूरे 60GiB टेबल को मेरे 100GiB PostgreSQL बफर कैश में लोड करता है।
सूदो

1

मुझे इसी तरह की समस्या थी:
सर्वर सेवा और सभी कैश किए गए डेटा को फिर से शुरू करने के बाद, कई प्रश्नों को पहली बार कहा जाता है जहां वास्तव में धीमी गति से, प्रश्नों की विशिष्ट जटिलता का कारण बनता है, जब तक कि सभी आवश्यक अनुक्रमित और डेटा को कैश नहीं किया गया था। इसका मतलब है कि उदाहरण के लिए, उपयोगकर्ताओं को हर "आइटम" (1-3 सेकंड का निष्पादन समय) और संबंधित डेटा को 50 मिलियन पंक्तियों से एक बार हिट करना होगा, इसलिए उपयोगकर्ता अब किसी भी अवांछित देरी का अनुभव नहीं करेंगे। उपयोगकर्ताओं को कष्टप्रद हैंग का अनुभव करने में पहले 3 घंटे लगते हैं, जब तक कि अधिकांश उपयोग किए गए डेटा को कैश नहीं किया जाता है और प्रोग्राम उत्पादन प्रदर्शन के साथ शीर्ष पायदान को बर्बाद कर रहे हैं, तब भी, 2 दिन कुछ अचानक कम देरी, जब कम पहली बार एक्सेस किए गए डेटा को मारते हैं ... , आँकड़ों के आंकड़ों आदि के लिए।

इसे हल करने के लिए, एक छोटी अजगर स्क्रिप्ट लिखी जो बड़े अनुक्रमित के साथ सबसे ज्यादा इस्तेमाल की जाने वाली तालिकाओं पर चयन करती है। इसे चलाने में 15 मिनट लगे, और प्रदर्शन में देरी नहीं हुई।


0

हम्म, हो सकता है COPY कमांड से मदद मिलेगी। बस स्टॉपआउट और इससे पढ़ने के लिए COPY निष्पादित करें। Pg_dump का उपयोग करके इसे करना संभव है:

pg_dump -U <user> -t <table> <database> > /dev/null

अन्य तरीका सभी टेबल फ़ाइलों को खोजने और चलाने का है cat <files> > /dev/null

यहाँ तालिका फ़ाइल नाम कैसे प्राप्त करने के लिए उदाहरण दिया गया है:

# SELECT oid, datname FROM pg_database ;
  oid  |  datname  
-------+-----------                                                                                                                                          
<...>
 16384 | test
-- out of database is 16384
# SELECT oid, relname FROM pg_class WHERE relname like 'fn%';
  oid  | relname 
-------+---------
 24576 | fn
(1 row)
-- oid of our table is 24576

इसलिए, तालिका की फ़ाइल / पथ / / से / pgsql / डेटा / आधार / 16384/24576 * है

आप जिस तरह से इंडेक्स और टोस्ट टेबल को पढ़ना चाहते हैं, उसी तरह से अपने ओड्स प्राप्त करें।

BTW, आपको इसकी आवश्यकता क्यों है? मेरा मानना ​​है कि Postgresql और OS सबसे स्मार्ट डेटा कैश करने और अच्छा बनाए रखने के लिए पर्याप्त स्मार्ट है। कैश दक्षता।


0

मैं QSoft से रामड्राइव का उपयोग करता हूं, जिसे विंडोज के लिए सबसे तेज रैमडिस्क के रूप में बेंचमार्क किया गया था । मैंने अभी उपयोग किया है

initdb -D e:\data

जहाँ e: \ RamDisk का स्थान है।


5
विंडोज पर पीजी एक प्रोडक्शन साइट के लिए एक बहुत बहादुर विकल्प है क्योंकि यह विंडोज पर निक्स (रैम से स्वतंत्र) की तुलना में धीमा है।
DrColossos
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.