टेबल फ़ंक्शन
मैं क्लाइंट और सर्वर भाषा (कोई अन्य भाषा का उपयोग नहीं किया जाता है) दोनों के रूप में एसक्यूएल का उपयोग करते हुए एक जीवित रहने के लिए बहुत उच्च गति, जटिल डेटाबेस माइग्रेशन करता हूं, सभी चल रहे सर्वर साइड, जहां कोड शायद ही कभी डेटाबेस इंजन से सतह पर आता है। टेबल फ़ंक्शन मेरे कार्य में बहुत बड़ी भूमिका निभाते हैं . मैं "कर्सर" का उपयोग नहीं करता क्योंकि वे मेरी प्रदर्शन आवश्यकताओं को पूरा करने में बहुत धीमे हैं, और मैं जो कुछ भी करता हूं वह परिणाम उन्मुख होता है। कर्सर के उपयोग को पूरी तरह से समाप्त करने, बहुत उच्च गति प्राप्त करने में टेबल फ़ंक्शंस मेरे लिए बहुत मददगार रहे हैं, और कोड वॉल्यूम को कम करने और सादगी में सुधार करने के लिए नाटकीय रूप से योगदान दिया है।
संक्षेप में, आप एक क्वेरी . का उपयोग करते हैं जो डेटा को एक टेबल फ़ंक्शन से दूसरे में पास करने के लिए दो (या अधिक) तालिका फ़ंक्शंस का संदर्भ देता है। तालिका फ़ंक्शन को कॉल करने वाला चयन क्वेरी परिणाम सेट डेटा को एक तालिका फ़ंक्शन से दूसरे में स्थानांतरित करने के लिए नाली के रूप में कार्य करता है। डीबी 2 प्लेटफॉर्म/संस्करण पर मैं काम करता हूं, और यह 9.1 पोस्टग्रेस मैनुअल पर एक त्वरित नज़र के आधार पर प्रकट होता है कि वही सच है, आप किसी भी तालिका फ़ंक्शन कॉल के इनपुट के रूप में कॉलम मानों की केवल एक पंक्ति पास कर सकते हैं, जैसा कि आपने खोजा है। हालांकि, क्योंकि तालिका फ़ंक्शन कॉल क्वेरी के परिणाम सेट प्रसंस्करण के बीच में होती है, आप प्रत्येक तालिका फ़ंक्शन कॉल पर एक संपूर्ण परिणाम सेट पास करने के समान प्रभाव प्राप्त करते हैं, यद्यपि, डेटाबेस इंजन प्लंबिंग में, डेटा पास किया जाता है प्रत्येक तालिका कार्य करने के लिए एक समय में केवल एक पंक्ति।
तालिका फ़ंक्शन इनपुट कॉलम की एक पंक्ति को स्वीकार करते हैं, और एक एकल परिणाम को कॉलिंग क्वेरी (यानी चयन) में वापस लौटाते हैं जिसे फ़ंक्शन कहा जाता है। तालिका फ़ंक्शन से वापस पास किए गए परिणाम सेट कॉलम कॉलिंग क्वेरी के परिणाम सेट का हिस्सा बन जाते हैं, और इसलिए अगले तालिका फ़ंक्शन में इनपुट के रूप में उपलब्ध होते हैं , जिसे बाद में उसी क्वेरी में संदर्भित किया जाता है, आमतौर पर बाद में शामिल होने के रूप में। पहली तालिका फ़ंक्शन के परिणाम कॉलम को दूसरी तालिका फ़ंक्शन में इनपुट (एक समय में एक पंक्ति) के रूप में खिलाया जाता है, जो इसके परिणाम सेट कॉलम को कॉलिंग क्वेरी के परिणाम सेट में देता है। पहली और दूसरी तालिका फ़ंक्शन परिणाम सेट कॉलम दोनों अब कॉलिंग क्वेरी के परिणाम सेट का हिस्सा हैं, और अब तीसरे टेबल फ़ंक्शन में इनपुट (एक समय में एक पंक्ति) के रूप में उपलब्ध हैं। प्रत्येक तालिका फ़ंक्शन कॉल कॉलिंग क्वेरी के परिणाम सेट को उसके द्वारा लौटाए गए कॉलम के माध्यम से विस्तृत करता है। यह तब तक जारी रह सकता है जब तक आप परिणाम सेट की चौड़ाई पर सीमा को मारना शुरू नहीं करते हैं, जो संभवतः एक डेटाबेस इंजन से दूसरे में भिन्न होता है।
इस उदाहरण पर विचार करें (जो पोस्टग्रेज की सिंटैक्स आवश्यकताओं या क्षमताओं से मेल नहीं खा सकता है क्योंकि मैं डीबी 2 पर काम करता हूं)। यह कई डिज़ाइन पैटर्नों में से एक है जिसमें मैं टेबल फ़ंक्शंस का उपयोग करता हूं, सरल लोगों में से एक है, जो मुझे लगता है कि बहुत ही उदाहरण है, और एक जिसकी मुझे आशा है कि व्यापक अपील होगी अगर टेबल फ़ंक्शंस भारी मुख्यधारा के उपयोग में थे (मेरी जानकारी के लिए वे नहीं हैं, लेकिन मुझे लगता है कि वे जितना उन्हें मिल रहा है उससे अधिक ध्यान देने योग्य हैं)।
इस उदाहरण में, उपयोग में आने वाले टेबल फ़ंक्शन हैं:VALIDATE_TODAYS_ORDER_BATCH, POST_TODAYS_ORDER_BATCH, और DATA_WAREHOUSE_TODAYS_ORDER_BATCH। जिस DB2 संस्करण पर मैं काम करता हूं, आप टेबल फ़ंक्शन को "टेबल (प्लेस टेबल फ़ंक्शन कॉल और पैरामीटर यहां)" के अंदर लपेटते हैं, लेकिन पोस्टग्रेज़ मैनुअल पर त्वरित नज़र के आधार पर ऐसा प्रतीत होता है कि आप "टेबल ()" रैपर को छोड़ देते हैं।पी>
create table TODAYS_ORDER_PROCESSING_EXCEPTIONS as (
select TODAYS_ORDER_BATCH.*
,VALIDATION_RESULT.ROW_VALID
,POST_RESULT.ROW_POSTED
,WAREHOUSE_RESULT.ROW_WAREHOUSED
from TODAYS_ORDER_BATCH
cross join VALIDATE_TODAYS_ORDER_BATCH ( ORDER_NUMBER, [either pass the remainder of the order columns or fetch them in the function] )
as VALIDATION_RESULT ( ROW_VALID ) --example: 1/0 true/false Boolean returned
left join POST_TODAYS_ORDER_BATCH ( ORDER_NUMBER, [either pass the remainder of the order columns or fetch them in the function] )
as POST_RESULT ( ROW_POSTED ) --example: 1/0 true/false Boolean returned
on ROW_VALIDATED = '1'
left join DATA_WAREHOUSE_TODAYS_ORDER_BATCH ( ORDER_NUMBER, [either pass the remainder of the order columns or fetch them in the function] )
as WAREHOUSE_RESULT ( ROW_WAREHOUSED ) --example: 1/0 true/false Boolean returned
on ROW_POSTED = '1'
where coalesce( ROW_VALID, '0' ) = '0' --Capture only exceptions and unprocessed work.
or coalesce( ROW_POSTED, '0' ) = '0' --Or, you can flip the logic to capture only successful rows.
or coalesce( ROW_WAREHOUSED, '0' ) = '0'
) with data
- यदि तालिका TODAYS_ORDER_BATCH में 1,000,000 पंक्तियाँ हैं, तो VALIDATE_TODAYS_ORDER_BATCH को प्रत्येक पंक्ति के लिए एक बार 1,000,000 बार कॉल किया जाएगा।
- यदि VALIDATE_TODAYS_ORDER_BATCH के अंदर 900,000 पंक्तियां सत्यापन पास कर लेती हैं, तो POST_TODAYS_ORDER_BATCH को 900,000 बार कॉल किया जाएगा।
- यदि केवल 850,000 पंक्तियाँ सफलतापूर्वक पोस्ट होती हैं, तो VALIDATE_TODAYS_ORDER_BATCH को LOL में कुछ खामियों को बंद करना होगा, और DATA_WAREHOUSE_TODAYS_ORDER_BATCH को 850,000 बार कॉल किया जाएगा।
- यदि डेटा वेयरहाउस में 850,000 पंक्तियों ने इसे सफलतापूर्वक बनाया है (अर्थात कोई अतिरिक्त अपवाद उत्पन्न नहीं हुए हैं), तो तालिका TODAYS_ORDER_PROCESSING_EXCEPTIONS को 1,00,000 - 850,000 =150,000 अपवाद पंक्तियों से भर दिया जाएगा।
इस उदाहरण में टेबल फ़ंक्शन कॉल केवल एक कॉलम लौटा रहे हैं, लेकिन वे कई कॉलम लौटा सकते हैं। उदाहरण के लिए, ऑर्डर पंक्ति को सत्यापित करने वाला तालिका फ़ंक्शन किसी ऑर्डर के सत्यापन में विफल होने का कारण वापस कर सकता है।
इस डिजाइन में, एचएलएल और डेटाबेस के बीच की सभी बातचीत को समाप्त कर दिया जाता है, क्योंकि एचएलएल अनुरोधकर्ता डेटाबेस को एक अनुरोध में पूरे बैच को संसाधित करने के लिए कह रहा है। इसके परिणामस्वरूप डेटाबेस में लाखों SQL अनुरोधों में कमी आती है, लाखों HLL प्रक्रिया या विधि कॉलों को हटाने में, और परिणामस्वरूप एक बड़ा रनटाइम सुधार प्रदान करता है। इसके विपरीत, लीगेसी कोड जो अक्सर एक समय में एक पंक्ति को संसाधित करता है, आम तौर पर TODAYS_ORDER_BATCH में प्रत्येक पंक्ति के लिए 1,000,000 लाने वाले SQL अनुरोध, साथ ही सत्यापन उद्देश्यों के लिए कम से कम 1,000,000 HLL और/या SQL अनुरोध, साथ ही कम से कम 1,000,000 HLL और /या SQL अनुरोध पोस्टिंग उद्देश्यों के लिए, प्लस 1,000,000 HLL और/या SQL अनुरोध डेटा वेयरहाउस को आदेश भेजने के लिए। दी गई, इस तालिका फ़ंक्शन डिज़ाइन का उपयोग करते हुए, तालिका फ़ंक्शन के अंदर SQL अनुरोध डेटाबेस को भेजे जा रहे हैं, लेकिन जब डेटाबेस स्वयं से अनुरोध करता है (अर्थात तालिका फ़ंक्शन के अंदर से), SQL अनुरोधों को बहुत तेज़ी से सेवित किया जाता है (विशेषकर की तुलना में) एक विरासत परिदृश्य जहां एचएलएल अनुरोधकर्ता रिमोट सिस्टम से सिंगल रो प्रोसेसिंग कर रहा है, WAN पर सबसे खराब स्थिति के साथ - OMG कृपया ऐसा न करें)।
यदि आप "परिणाम सेट प्राप्त करने" के लिए तालिका फ़ंक्शन का उपयोग करते हैं और फिर उस परिणाम सेट को अन्य तालिकाओं में शामिल करते हैं तो आप आसानी से प्रदर्शन समस्याओं में भाग ले सकते हैं। उस स्थिति में, SQL ऑप्टिमाइज़र भविष्यवाणी नहीं कर सकता कि तालिका फ़ंक्शन से पंक्तियों का कौन सा सेट वापस किया जाएगा, और इसलिए यह बाद की तालिकाओं में शामिल होने का अनुकूलन नहीं कर सकता है। इस कारण से, मैं परिणाम सेट लाने के लिए शायद ही कभी उनका उपयोग करता हूं, जब तक कि मुझे पता न हो कि परिणाम सेट पंक्तियों की एक बहुत छोटी संख्या होगी, इसलिए प्रदर्शन समस्या पैदा नहीं कर रहा है, या मुझे बाद की तालिकाओं में शामिल होने की आवश्यकता नहीं है।पी>
मेरी राय में, टेबल फ़ंक्शंस का कम उपयोग होने का एक कारण यह है कि उन्हें अक्सर परिणाम सेट लाने के लिए केवल एक उपकरण के रूप में माना जाता है, जो अक्सर खराब प्रदर्शन करता है, इसलिए वे उपयोग करने के लिए "खराब" टूल के रूप में लिखे जाते हैं।
टेबल फ़ंक्शंस सर्वर पर अधिक कार्यक्षमता को आगे बढ़ाने के लिए, डेटाबेस सर्वर और रिमोट सिस्टम पर प्रोग्राम के बीच के अधिकांश चैट को समाप्त करने के लिए, और यहां तक कि एक ही सर्वर पर डेटाबेस सर्वर और बाहरी प्रोग्राम के बीच चैटर को खत्म करने के लिए बेहद उपयोगी हैं। यहां तक कि एक ही सर्वर पर कार्यक्रमों के बीच चैटिंग कई लोगों के एहसास से अधिक ओवरहेड लेती है, और इसमें से अधिकतर अनावश्यक है। टेबल फ़ंक्शंस की शक्ति का दिल परिणाम सेट प्रसंस्करण के अंदर क्रियाओं को करने के लिए उनका उपयोग करने में निहित है।
तालिका फ़ंक्शंस का उपयोग करने के लिए और अधिक उन्नत डिज़ाइन पैटर्न हैं जो उपरोक्त पैटर्न पर निर्मित होते हैं, जहाँ आप परिणाम सेट प्रसंस्करण को और भी अधिक बढ़ा सकते हैं, लेकिन यह पोस्ट अधिकांश के लिए पहले से ही अवशोषित करने के लिए बहुत कुछ है।