मेरी "घुटने-झटका प्रदर्शन ट्यूनिंग" श्रृंखला की इस निरंतरता में, मैं अस्थायी तालिकाओं का उपयोग करने के साथ देखी जाने वाली चार सामान्य समस्याओं पर चर्चा करना चाहता हूं। इनमें से कोई भी समस्या कार्यभार को पंगु बना सकती है, इसलिए वे आपके परिवेश के बारे में जानने और तलाशने लायक हैं।
समस्या 1:अस्थायी तालिकाओं का उपयोग करना जहां उनकी आवश्यकता नहीं है
https://www.flickr। com/photos/tea_time/3890677277/अस्थायी तालिकाओं में कई प्रकार के उपयोग होते हैं (शायद बाद में उपयोग के लिए मध्यवर्ती परिणाम सेट को स्टोर करना सबसे आम है), लेकिन आपको यह याद रखना होगा कि जब आप किसी क्वेरी में एक अस्थायी तालिका पेश करते हैं, तो आप डेटा के प्रवाह को बाधित कर रहे हैं क्वेरी प्रोसेसर।
एक अस्थायी तालिका की आबादी को एक कठिन पड़ाव के रूप में सोचें, क्योंकि मध्यवर्ती परिणाम सेट का उत्पादन करने के लिए एक प्रश्न है (चलिए इसे निर्माता कहते हैं), जिसे तब अस्थायी तालिका में tempdb में संग्रहीत किया जाता है, और फिर अगली क्वेरी (चलिए कॉल करें) यह उपभोक्ता) को अस्थायी तालिका से डेटा को फिर से पढ़ना होगा।
मैंने अक्सर पाया है कि अस्थायी तालिका पूरी तरह से हटा दिए जाने पर वर्कलोड के कुछ हिस्से वास्तव में बेहतर प्रदर्शन करते हैं, इसलिए डेटा क्वेरी के निर्माता भाग से क्वेरी के उपभोक्ता भाग में tempdb में बने रहने के बिना बहता है, और क्वेरी अनुकूलक एक अधिक इष्टतम समग्र योजना तैयार कर सकता है।
अब आप सोच रहे होंगे, "तो कोई अस्थायी तालिका का उपयोग क्यों करेगा यदि यह चीजों को धीमा कर देती है?" - और ठीक ही तो! ऐसे मामलों में, मैंने पाया है कि विकास दल में एक अस्थायी तालिका का उपयोग संस्थागत हो गया है; किसी ने पाया कि कई साल पहले एक अस्थायी तालिका का उपयोग करने से प्रदर्शन में वृद्धि हुई, इसलिए अस्थायी तालिकाएँ डिफ़ॉल्ट डिज़ाइन विकल्प बन गईं।
इसे बदलना मुश्किल हो सकता है, खासकर यदि आपके पास एक वरिष्ठ डेवलपर या प्रबंधक है जो आश्वस्त है कि अस्थायी तालिकाओं का हमेशा उपयोग किया जाना चाहिए। कोशिश करने की साधारण बात यह है कि एक महंगी क्वेरी (उदाहरण के लिए, एक लंबे समय तक चलने वाली, या एक जिसे प्रति सेकंड कई बार निष्पादित किया जाता है) को चुनना है और यह देखने के लिए एक या अधिक अस्थायी तालिकाओं को हटा दें कि उनके बिना प्रदर्शन बढ़ता है या नहीं। और अगर ऐसा है, तो घुसपैठियों को दिखाने के लिए आपके पास सबूत हैं!
समस्या 2:अस्थायी तालिकाओं को भरते समय फ़िल्टरिंग की कमी
यहां तक कि अगर आप एक अस्थायी तालिका को हटा नहीं सकते हैं, तो आप यह सुनिश्चित करके प्रदर्शन में काफी सुधार करने में सक्षम हो सकते हैं कि अस्थायी तालिका को पॉप्युलेट करने वाला कोड स्रोत तालिकाओं से निकाले गए डेटा को सही ढंग से फ़िल्टर कर रहा है।
मैंने कितनी बार एक अस्थायी तालिका को कोड के साथ पॉप्युलेट होते देखा है जो SELECT *
के रूप में शुरू होता है, की संख्या खो चुका है , में कुछ अप्रतिबंधित जोड़ शामिल हैं, और इसमें कोई WHERE क्लॉज़ नहीं है, और फिर बाद की क्वेरी जो अस्थायी तालिका का उपयोग करती है, केवल कुछ कॉलम का उपयोग करती है और पंक्तियों की संख्या को बहुत कम करने के लिए WHERE क्लॉज़ है।
मुझे एक मामला याद है जहां एक संग्रहीत प्रक्रिया में एक अस्थायी तालिका मुख्य डेटाबेस से 15 साल के डेटा को एकत्रित कर रही थी, और उसके बाद केवल चालू वर्ष के डेटा का उपयोग किया जा रहा था। यह बार-बार tempdb बढ़ने का कारण बन रहा था जब तक कि यह डिस्क वॉल्यूम पर जगह से बाहर नहीं हो गया, और संग्रहीत प्रक्रिया विफल हो जाएगी।
जब भी आप एक अस्थायी तालिका को पॉप्युलेट कर रहे हों, केवल आवश्यक स्रोत तालिका कॉलम का उपयोग करें, और केवल उन पंक्तियों का उपयोग करें जो आवश्यक हैं - यानी फ़िल्टर को अस्थायी तालिका जनसंख्या कोड में अनुमानित करें। यह न केवल tempdb में जगह बचाएगा, यह स्रोत तालिका से अनावश्यक डेटा की प्रतिलिपि न करने से भी बहुत समय बचाएगा (और संभावित रूप से डिस्क से स्रोत डेटाबेस पृष्ठों को पढ़ने की आवश्यकता को हटा देगा)।
समस्या 3:गलत अस्थायी तालिका अनुक्रमण
नियमित तालिकाओं की तरह, आपको केवल वही अनुक्रमणिकाएँ बनानी चाहिए जो वास्तव में बाद के क्वेरी कोड द्वारा क्वेरी के प्रदर्शन में मदद करने के लिए उपयोग की जा रही हैं। मैंने बहुत सारे मामले देखे हैं जहां प्रति अस्थायी तालिका कॉलम में एक गैर-अनुक्रमित अनुक्रमणिका है, और बाद के कोड का विश्लेषण किए बिना चुने गए सिंगल-कॉलम इंडेक्स अक्सर काफी बेकार होते हैं। अब अस्थायी तालिका को पॉप्युलेट करते समय बेकार गैर-संकुल अनुक्रमणिका को फ़िल्टरिंग की कमी के साथ संयोजित करें, और आपको tempdb की भारी सूजन के लिए एक नुस्खा मिल गया है।
साथ ही, सामान्य रूप से, तालिका के पॉप्युलेट होने के बाद अनुक्रमणिका बनाना तेज़ होता है। यह अतिरिक्त बोनस देता है कि इंडेक्स में सटीक आंकड़े होंगे, जो क्वेरी को और मदद कर सकते हैं क्योंकि क्वेरी ऑप्टिमाइज़र सटीक कार्डिनैलिटी अनुमान करने में सक्षम होगा।
गैर-संकुलित अनुक्रमितों का एक गुच्छा होने से, जिनका उपयोग नहीं किया जाता है, न केवल डिस्क स्थान, बल्कि उन्हें बनाने के लिए आवश्यक समय भी बर्बाद होता है। यदि यह कोड में है जिसे अक्सर निष्पादित किया जाता है, तो हर बार कोड चलने पर बनाए गए इन अनावश्यक अनुक्रमणिकाओं को हटाने से समग्र प्रदर्शन पर महत्वपूर्ण प्रभाव पड़ सकता है।
समस्या 4:tempdb कुंडी विवाद
tempdb में एक लैचिंग बाधा होने के लिए यह काफी आम है जिसे अस्थायी तालिका उपयोग पर वापस देखा जा सकता है। यदि बहुत सारे समवर्ती कनेक्शन चल रहे कोड हैं जो अस्थायी तालिकाओं को बनाते और छोड़ते हैं, तो स्मृति में डेटाबेस के आवंटन बिटमैप तक पहुंच एक महत्वपूर्ण बाधा बन सकती है।
ऐसा इसलिए है क्योंकि एक समय में केवल एक थ्रेड आवंटन बिटमैप को पृष्ठों (अस्थायी तालिका से) को आवंटित या हटाए जाने के रूप में चिह्नित करने के लिए बदल सकता है, और इसलिए अन्य सभी थ्रेड्स को वर्कलोड थ्रूपुट को कम करते हुए इंतजार करना पड़ता है। भले ही SQL सर्वर 2005 के बाद से एक अस्थायी टेबल कैश रहा हो, यह बहुत बड़ा नहीं है, और इस पर प्रतिबंध हैं कि अस्थायी तालिका को कब कैश किया जा सकता है (उदाहरण के लिए केवल जब यह आकार में 8MB से कम हो)।
इस समस्या को हल करने के पारंपरिक तरीके ट्रेस फ़्लैग 1118 और कई tempdb डेटा फ़ाइलों का उपयोग करना है (अधिक जानकारी के लिए यह ब्लॉग पोस्ट देखें), लेकिन एक और बात पर विचार करना अस्थायी तालिकाओं को पूरी तरह से हटा देना है!
सारांश
अस्थायी तालिकाएँ बहुत उपयोगी हो सकती हैं, लेकिन वे बहुत आसानी से और आमतौर पर गलत तरीके से उपयोग की जाती हैं। जब भी आप अस्थायी तालिका का उपयोग करते हुए लिख रहे हों (या कोड की समीक्षा कर रहे हों), तो निम्नलिखित पर विचार करें:
- क्या यह अस्थायी तालिका वास्तव में आवश्यक है ?
- क्या वह कोड है जो सही फ़िल्टरिंग का उपयोग करके तालिका को भरता है अस्थायी तालिका आकार को सीमित करने के लिए?
- इंडेक्स टेबल आबादी के बाद बनाए गए हैं (सामान्य तौर पर) और इंडेक्स का उपयोग किया जा रहा है बाद के कोड द्वारा?
पॉल व्हाइट के पास अस्थायी वस्तु उपयोग और कैशिंग के बारे में कुछ बेहतरीन पोस्ट हैं (यहां और यहां) जिन्हें मैं भी पढ़ने की सलाह देता हूं।
और एक आखिरी बात, यदि आप एक अस्थायी तालिका का उपयोग नहीं करने का निर्णय लेते हैं, तो इसे केवल एक तालिका चर, एक सामान्य तालिका अभिव्यक्ति, या एक कर्सर से प्रतिस्थापित न करें (ये सभी सामान्य तरीके हैं जिनसे लोग "अनुकूलित" करने का प्रयास करते हैं। अस्थायी तालिका) - कोड लिखने (पुनः) का सबसे प्रभावी तरीका पता करें - कोई "एक आकार सभी फिट बैठता है" उत्तर नहीं है।
अगली बार तक, समस्या निवारण के लिए शुभकामनाएँ!