Postgres-XL में, अनुक्रमों को वैश्विक लेनदेन प्रबंधक (GTM) में बनाए रखा जाता है ताकि यह सुनिश्चित किया जा सके कि उन्हें कई नोड्स से वृद्धि होने पर गैर-परस्पर विरोधी मान असाइन किए गए हैं। यह एक सीरियल कॉलम वाली तालिका में हजारों INSERT करने वाली क्वेरी के लिए महत्वपूर्ण ओवरहेड जोड़ता है, एक समय में एक क्रम को बढ़ाता है और प्रत्येक INSERT के लिए GTM के लिए एक नेटवर्क राउंडट्रिप बनाता है।
शॉन थॉमस ने हाल ही में एक ब्लॉग में शिकायत की थी कि INSERTs ने पोस्टग्रेज-एक्सएल पर वैनिला पोस्टग्रेएसक्यूएल की तुलना में धीमी गति से चल रहा है। अनुक्रमों के प्रदर्शन में सुधार करने का एक तरीका पहले से ही है, लेकिन यह स्पष्ट रूप से अच्छी तरह से विज्ञापित नहीं है। मुझे लगा कि सुविधा को समझाने का यह एक अच्छा अवसर है।
Postgres-XL एक उपयोगकर्ता-सेटटेबल GUC प्रदान करता है जिसे sequence_range . कहा जाता है . प्रत्येक बैकएंड इस GUC द्वारा नियंत्रित अनुक्रम मानों के एक ब्लॉक का अनुरोध करता है। यह देखते हुए कि COPY लोकप्रिय रूप से Postgres में डेटा को बल्क लोड करने के लिए उपयोग किया जाता है, Postgres-XL स्वचालित रूप से COPY ऑपरेशन के दौरान इस GUC को ओवरराइड करता है और इसे 1000 पर सेट करता है, इस प्रकार COPY प्रदर्शन में नाटकीय रूप से सुधार होता है। दुर्भाग्य से, नियमित INSERTs के लिए, डिफ़ॉल्ट 1 है और जब तक उपयोगकर्ता स्पष्ट रूप से sequence_range सेट नहीं करता है यथोचित उच्च मूल्य के लिए, INSERT का प्रदर्शन प्रभावित होता है। शॉन द्वारा अपने ब्लॉग पोस्ट में उपयोग किए गए समान नमूना स्कीमा का उपयोग करके यहां एक उदाहरण दिया गया है।
CREATE TABLE sensor_log ( sensor_log_id SERIAL PRIMARY KEY, location VARCHAR NOT NULL, reading BIGINT NOT NULL, reading_date TIMESTAMP NOT NULL ) DISTRIBUTE BY HASH (sensor_log_id); postgres=# \timing Timing is on. postgres=# INSERT INTO sensor_log (location, reading, reading_date) SELECT s.id % 1000, s.id % 100, now() - (s.id || 's')::INTERVAL FROM generate_series(1, 40000) s(id); INSERT 0 40000 Time: 12067.911 ms postgres=# set sequence_range TO 1000; SET Time: 1.231 ms postgres=# INSERT INTO sensor_log (location, reading, reading_date) SELECT s.id % 1000, s.id % 100, now() - (s.id || 's')::INTERVAL FROM generate_series(1, 40000) s(id); INSERT 0 40000 Time: 397.406 ms
तो अनुक्रम_रेंज . को उचित रूप से सेट करके 1000 तक, INSERT क्वेरी के प्रदर्शन में लगभग 30 गुना सुधार हुआ।
जब यह सुविधा जोड़ी गई थी, तो सीक्वेंस_रेंज जीयूसी का डिफ़ॉल्ट मान 1 पर सेट किया गया था क्योंकि यह अनुक्रम मानों में छेद छोड़ सकता है। लेकिन एक बहुत ही सामान्य उपयोग के मामले के प्रदर्शन के निहितार्थ को देखते हुए, हमने डिफ़ॉल्ट को 1000 तक बढ़ाने का फैसला किया और यह अब रिपॉजिटरी की XL9_5_STABLE शाखा के लिए प्रतिबद्ध है।
यह ध्यान रखना महत्वपूर्ण है कि sequence_range . का उच्च मान होने पर अनुक्रमों और धारावाहिकों के प्रदर्शन में सुधार करेगा, यह अनुक्रम श्रेणियों में बड़े छेद भी छोड़ सकता है क्योंकि अनुक्रम श्रेणियां बैकएंड स्तर पर कैश की जाती हैं। इस समस्या को हल करने के लिए, Postgres-XL अनुक्रम निर्माण समय पर उपयोग किए जाने वाले निर्दिष्ट CACHE पैरामीटर मान से शुरू होता है और यदि अनुक्रम बहुत अधिक दर पर खपत किया जा रहा है तो इसे हर बार (सीक्वेंस_रेंज द्वारा सीमित) दोगुना कर देता है।
अनुक्रम के CACHE पैरामीटर मान को बढ़ाकर भी इसी तरह का सुधार प्राप्त किया जा सकता है ताकि बैकएंड स्तर पर अनुक्रम मानों का एक हिस्सा कैश किया जा सके। निम्नलिखित उदाहरण दिखाता है कि सीरियल कॉलम के लिए यह कैसे करना है। लेकिन अनुक्रम_रेंज GUC वैश्विक डिफ़ॉल्ट को ओवरराइड करने का एक आसान तरीका प्रदान करता है और यह भी सुनिश्चित करता है कि अनुक्रम केवल तभी कैश किए जाते हैं जब वे बहुत तेज़ी से बढ़ रहे हों।
postgres=# ALTER SEQUENCE sensor_log_sensor_log_id_seq CACHE 1000; ALTER SEQUENCE Time: 8.683 ms postgres=# SET sequence_range TO 1; SET Time: 2.341 ms postgres=# INSERT INTO sensor_log (location, reading, reading_date) SELECT s.id % 1000, s.id % 100, now() - (s.id || 's')::INTERVAL FROM generate_series(1, 40000) s(id); INSERT 0 40000 Time: 418.068 ms
प्रदर्शन को बेहतर बनाने के लिए आप इनमें से कोई भी तकनीक चुन सकते हैं। हालांकि अब sequence_range . का डिफ़ॉल्ट मान 1000 में बदल दिया गया है, बहुत से उपयोगकर्ताओं को प्रदर्शन में अंतर दिखाई नहीं दे सकता है।