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

विभाजन-वार जुड़ने के लिए उन्नत विभाजन मिलान

इससे पहले मैंने PostgreSQL में विभाजन-वार शामिल होने के बारे में एक ब्लॉग लिखा था। उस ब्लॉग में, मैंने एक उन्नत विभाजन मिलान तकनीक के बारे में बात की थी जो अधिक मामलों में विभाजन के अनुसार जुड़ने की अनुमति देगी। इस ब्लॉग में हम इस तकनीक पर विस्तार से चर्चा करेंगे।

संक्षेप में, मूल विभाजन मिलान तकनीक दो विभाजित तालिकाओं के बीच जुड़ने की अनुमति देती है विभाजन-वार जुड़ने की तकनीक का उपयोग करके प्रदर्शन किया जा सकता है यदि दो विभाजित तालिकाओं में बिल्कुल मिलान विभाजन सीमाएं हैं उदा। विभाजित टेबल prt1 और prt2 नीचे वर्णित है

psql> \d+ prt1
... [output clipped]
Partition key: RANGE (a)
Partitions: prt1_p1 FOR VALUES FROM (0) TO (5000),
prt1_p2 FOR VALUES FROM (5000) TO (15000),
prt1_p3 FOR VALUES FROM (15000) TO (30000)

और

psql>\d+ prt2
... [ output clipped ]
Partition key: RANGE (b)
Partitions: prt2_p1 FOR VALUES FROM (0) TO (5000),
prt2_p2 FOR VALUES FROM (5000) TO (15000),
prt2_p3 FOR VALUES FROM (15000) TO (30000)

उनकी पार्टीशन कुंजी पर prt1 और prt2 के बीच एक जुड़ाव (a) उनके मेल खाने वाले पार्टिशन के बीच जॉइन में टूट जाता है यानी prt1_p1 prt2_p1, prt1_p2 जॉइन करता है prt2_p2 और prt1_p3 जॉइन करता है prt2_p3। इन तीनों जॉइन के परिणाम एक साथ prt1 और prt2 के बीच जुड़ने का परिणाम बनाते हैं। इसके कई फायदे हैं जैसा कि मेरे पिछले ब्लॉग में चर्चा की गई थी। हालांकि, मूल विभाजन मिलान अलग-अलग विभाजन सीमाओं के साथ दो विभाजित तालिकाओं में शामिल नहीं हो सकता है। उपरोक्त उदाहरण में, यदि prt1 में (30000) से (50000) तक के मानों के लिए एक अतिरिक्त विभाजन prt1_p4 है, तो मूल विभाजन मिलान prt1 और prt2 के बीच के जोड़ को विभाजन-वार जोड़ में बदलने में मदद नहीं करेगा क्योंकि उनके पास बिल्कुल मेल खाने वाला विभाजन नहीं है। सीमा।

कई एप्लिकेशन सक्रिय रूप से उपयोग किए गए डेटा और पुराने डेटा को अलग करने के लिए विभाजन का उपयोग करते हैं, एक तकनीक जिसकी मैंने अपने दूसरे ब्लॉग में चर्चा की थी। बासी डेटा अंततः विभाजनों को छोड़ कर हटा दिया जाता है। ताजा डेटा को समायोजित करने के लिए नए विभाजन बनाए गए हैं। ऐसी दो विभाजित तालिकाओं के बीच एक जुड़ाव ज्यादातर विभाजन-वार जुड़ाव का उपयोग करेगा क्योंकि अधिकांश समय उनके पास मिलान वाले विभाजन होंगे। लेकिन जब इन तालिकाओं में से एक में एक सक्रिय विभाजन जोड़ा जाता है या एक पुराना हटा दिया जाता है, तो उनकी विभाजन सीमाएं तब तक मेल नहीं खातीं जब तक कि दूसरी तालिका भी इसी तरह के ऑपरेशन से नहीं गुजरती। उस अंतराल के दौरान इन दो तालिकाओं के बीच में शामिल होने से विभाजन-वार जुड़ाव का उपयोग नहीं होगा और निष्पादित होने में असामान्य रूप से अधिक समय लग सकता है। हम नहीं चाहते कि इस छोटी अवधि के दौरान खराब प्रदर्शन करने के लिए डेटाबेस को हिट करने वाला एक जॉइन विभाजन-वार जॉइन का उपयोग नहीं कर सकता है। उन्नत विभाजन मिलान एल्गोरिथ्म इस और अधिक जटिल मामलों में मदद करता है जहाँ विभाजन की सीमाएँ बिल्कुल मेल नहीं खाती हैं।

उन्नत विभाजन मिलान एल्गोरिथ्म

उन्नत विभाजन मिलान तकनीक दो विभाजित तालिकाओं से मेल खाने वाले विभाजन ढूंढती है, भले ही उनकी विभाजन सीमा बिल्कुल मेल न खाए। यह मर्ज जॉइन एल्गोरिथम के समान दोनों तालिकाओं की सीमाओं की उनके क्रमबद्ध क्रम में तुलना करके मिलान विभाजन ढूंढता है। कोई भी दो विभाजन, प्रत्येक विभाजित तालिका में से एक, जिसकी सीमाएँ बिल्कुल मेल खाती हैं या ओवरलैप होती हैं, उन्हें शामिल होने वाले भागीदार माना जाता है क्योंकि उनमें शामिल होने वाली पंक्तियाँ हो सकती हैं। उपरोक्त उदाहरण को जारी रखते हुए, मान लें कि एक सक्रिय नया विभाजन prt2_p4 prt4 में जुड़ जाता है। विभाजित टेबल अब इस तरह दिखती हैं:

psql>\d+ prt1
... [output clipped]
Partition key: RANGE (a)
Partitions: prt1_p1 FOR VALUES FROM (0) TO (5000),
prt1_p2 FOR VALUES FROM (5000) TO (15000),
prt1_p3 FOR VALUES FROM (15000) TO (30000)

और

psql>\d+ prt2
... [ output clipped ]
Partition key: RANGE (b)
Partitions: prt2_p1 FOR VALUES FROM (0) TO (5000),
prt2_p2 FOR VALUES FROM (5000) TO (15000),
prt2_p3 FOR VALUES FROM (15000) TO (30000),
prt2_p4 FOR VALUES FROM (30000) TO (50000)

यह देखना आसान है कि prt1_p1 और prt2_p1, prt1_p2 और prt2_p2, और prt1_p3 और prt2_p3 की विभाजन सीमाएं मेल खाती हैं। लेकिन मूल विभाजन मिलान के विपरीत, उन्नत विभाजन मिलान को पता चल जाएगा कि prt2_p4 का prt1 में कोई मिलान विभाजन नहीं है। यदि prt1 और prt2 के बीच जुड़ाव एक INNER जॉइन है या जब prt2 जॉइन में INNER संबंध है, तो जॉइन परिणाम में prt2_p4 से कोई पंक्ति नहीं होगी। मेल खाने वाले विभाजनों और विभाजनों के बारे में विस्तृत जानकारी के साथ सक्षम, जो केवल विभाजन सीमा से मेल खाते हैं या नहीं, क्वेरी ऑप्टिमाइज़र यह तय कर सकता है कि विभाजन-वार जॉइन का उपयोग करना है या नहीं। इस मामले में, यह prt2_p4 को एक तरफ छोड़कर, मिलान करने वाले विभाजनों के बीच जुड़ने के रूप में शामिल होने का चयन करेगा। लेकिन यह "उन्नत" विभाजन मिलान जैसा नहीं है। आइए इस बार सूची विभाजित तालिकाओं का उपयोग करके थोड़ा और जटिल मामला देखें:

psql>\d+ plt1
Partition key: LIST (c)
Partitions: plt1_p1 FOR VALUES IN ('0001', '0003'),
plt1_p2 FOR VALUES IN ('0004', '0006'),
plt1_p3 FOR VALUES IN ('0008', '0009')

और

psql>\d+ plt2
Partition key: LIST (c)
Partitions: plt2_p1 FOR VALUES IN ('0002', '0003'),
plt2_p2 FOR VALUES IN ('0004', '0006'),
plt2_p3 FOR VALUES IN ('0007', '0009')

ध्यान दें कि दोनों संबंधों में ठीक तीन विभाजन हैं लेकिन विभाजन मूल्य सूची भिन्न है। plt1_p2 विभाजन से संबंधित सूची plt2_p2 से बिल्कुल मेल खाती है। इसके अलावा कोई भी दो विभाजन, दोनों तरफ से एक, बिल्कुल मेल खाने वाली सूचियां नहीं हैं। उन्नत विभाजन मिलान एल्गोरिथ्म यह निष्कर्ष निकालता है कि plt1_p1 और plt2_p1 में अतिव्यापी सूचियाँ हैं और उनकी सूचियाँ अन्य संबंध से किसी अन्य विभाजन के साथ ओवरलैप नहीं होती हैं। इसी तरह plt1_p3 और plt2_p3 के लिए। क्वेरी ऑप्टिमाइज़र तब देखता है कि plt1 और plt2 के बीच जुड़ाव को मिलान वाले पार्टिशन यानी plt1_p1 और plt2_p1, plt1_p2, और plt2_p2, और plt1_p3 और plt2_p3 को मिलाकर विभाजन-वार जॉइन के रूप में निष्पादित किया जा सकता है। एल्गोरिथ्म सूची के और भी अधिक जटिल विभाजन बाध्य सेटों के साथ-साथ श्रेणी विभाजित तालिकाओं में मिलान विभाजन पा सकता है। लेकिन हम संक्षिप्तता के लिए उन्हें कवर नहीं करेंगे। इच्छुक और अधिक साहसी पाठक कमिटमेंट पर एक नज़र डाल सकते हैं। इसमें कई टेस्टकेस भी हैं, जो विभिन्न परिदृश्य दिखाते हैं जहां उन्नत विभाजन मिलान एल्गोरिदम का उपयोग किया जाता है।

सीमाएं

बाहरी जोड़ मेल खाने वाले विभाजनों के साथ आंतरिक भाग में गायब हैं

PostgreSQL दुनिया में बाहरी जुड़ाव एक विशेष समस्या है। prt2 लेफ्ट जॉइन prt1 पर विचार करें, उपरोक्त उदाहरण में, जहां prt2 एक बाहरी संबंध है। prt2_p4 का prt1 में कोई जॉइनिंग पार्टनर नहीं है और फिर भी उस पार्टीशन में पंक्तियाँ शामिल होने के परिणाम का हिस्सा होनी चाहिए क्योंकि वे बाहरी संबंध से संबंधित हैं। PostgreSQL में जब किसी जॉइन का INNER साइड खाली होता है, तो इसे एक "डमी" रिलेशन द्वारा दर्शाया जाता है, जो कोई पंक्तियाँ नहीं छोड़ता है, लेकिन फिर भी उस रिलेशन की स्कीमा को जानता है। आम तौर पर एक "डमी" संबंध एक गैर-डमी संबंध से उभरता है जो कुछ क्वेरी अनुकूलन जैसे बाधा बहिष्करण के कारण किसी भी पंक्ति को उत्सर्जित नहीं करेगा। PostgreSQL का क्वेरी ऑप्टिमाइज़र ऐसे गैर-डमी संबंध को डमी के रूप में चिह्नित करता है और इस तरह के जुड़ाव को निष्पादित करते समय निष्पादक सामान्य रूप से आगे बढ़ता है। लेकिन जब बाहरी विभाजन के लिए कोई मेल खाने वाला आंतरिक विभाजन नहीं होता है, तो कोई "मौजूदा इकाई" नहीं होती है जिसे "डमी" के रूप में चिह्नित किया जा सकता है। उदाहरण के लिए, इस मामले में कोई prt1_p4 नहीं है जो बाहरी prt2_p4 में शामिल होने वाले डमी आंतरिक विभाजन का प्रतिनिधित्व कर सकता है। अभी, PostgreSQL के पास योजना के दौरान ऐसे "डमी" संबंधों को "बनाने" का कोई तरीका नहीं है। इसलिए क्वेरी ऑप्टिमाइज़र इस मामले में विभाजन-वार शामिल होने का उपयोग नहीं करता है।

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

मैं इस बात पर जोर देना चाहता हूं कि बाहरी जोड़ जहां आंतरिक जोड़ पर कोई लापता विभाजन नहीं हैं, वहां विभाजन-वार जुड़ाव का उपयोग करें।

एकाधिक मेल खाने वाले विभाजन

जब तालिकाओं को इस तरह विभाजित किया जाता है कि एक तरफ से कई विभाजन दूसरी तरफ एक या एक से अधिक विभाजन से मेल खाते हैं, तो विभाजन-वार जुड़ाव का उपयोग नहीं किया जा सकता है क्योंकि नियोजन समय के दौरान "संलग्न" संबंध को प्रेरित करने का कोई तरीका नहीं है जो दो या अधिक का प्रतिनिधित्व करता है एक साथ विभाजन। उम्मीद है कि हम कभी-कभी उस सीमा को भी हटा देंगे और उन मामलों में भी विभाजन-वार शामिल होने की अनुमति देंगे।

विभाजित तालिकाओं को हैश करें

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

जब उन्नत विभाजन मिलान एल्गोरिथ्म मेल खाने वाले विभाजन खोजने में विफल रहता है या उपरोक्त सीमाओं के कारण विभाजन-वार जुड़ाव का उपयोग नहीं किया जा सकता है, तो PostgreSQL नियमित तालिकाओं के रूप में विभाजित तालिकाओं में शामिल होने के लिए वापस आ जाता है।

उन्नत विभाजन मिलान समय

फीचर के बारे में टिप्पणी करते हुए साइमन ने एक दिलचस्प बात कही। विभाजित तालिका के विभाजन अक्सर नहीं बदलते हैं इसलिए उन्नत विभाजन मिलान का परिणाम लंबी अवधि के लिए समान रहना चाहिए। हर बार इन तालिकाओं को शामिल करने वाली क्वेरी को निष्पादित करने पर इसकी गणना करना अनावश्यक है। इसके बजाय हम कुछ कैटलॉग में मेल खाने वाले विभाजनों के सेट को सहेज सकते हैं और हर बार विभाजन बदलने पर इसे ताज़ा कर सकते हैं। यह कुछ काम है लेकिन यह प्रत्येक प्रश्न के लिए विभाजन के मिलान में लगने वाले समय के लायक है।

इन सभी सीमाओं के बावजूद, आज हमारे पास एक बहुत ही उपयोगी समाधान है जो अधिकांश व्यावहारिक मामलों में कार्य करता है। यह कहने की आवश्यकता नहीं है कि यह सुविधा FDW जॉइन पुश डाउन के साथ निर्बाध रूप से काम करती है, जिससे PostgreSQL के पास पहले से मौजूद शार्डिंग क्षमताओं में सुधार होता है!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL के लिए Percona वितरण की निगरानी - प्रमुख मेट्रिक्स

  2. Nagios का उपयोग करके PostgreSQL की निगरानी कैसे करें

  3. PL/pgSQL के अंदर INSERT के बाद डिफ़ॉल्ट सीरियल मान प्राप्त करें

  4. पीजी-वादे में क्वेरी टाइमआउट

  5. क्या मैं किसी अन्य INSERT में INSERT...RETURNING के रिटर्न वैल्यू का उपयोग कर सकता हूं?