इस लेख में, हम तालिका चर के प्रदर्शन के विषय पर बात करने जा रहे हैं। SQL सर्वर में, हम वेरिएबल बना सकते हैं जो पूर्ण तालिकाओं के रूप में काम करेंगे। शायद, अन्य डेटाबेस में समान क्षमताएं होती हैं, हालांकि, मैंने ऐसे चर का उपयोग केवल MS SQL सर्वर में किया है।
इस प्रकार, आप निम्नलिखित लिख सकते हैं:
@t को टेबल (इंट वैल्यू) घोषित करें
यहां, हम @t चर को एक तालिका के रूप में घोषित करते हैं जिसमें पूर्णांक प्रकार का एकल मान स्तंभ होगा। अधिक जटिल तालिकाएँ बनाना संभव है, हालाँकि, हमारे उदाहरण में, अनुकूलन का पता लगाने के लिए एक कॉलम पर्याप्त है।
अब, हम इस वेरिएबल का उपयोग अपने प्रश्नों में कर सकते हैं। हम इसमें बहुत अधिक डेटा जोड़ सकते हैं और इस चर से डेटा पुनर्प्राप्ति कर सकते हैं:
उपयोगकर्ता से @tselect UserID में डालें या @t से * चुनें
मैंने देखा कि बड़े चयन के लिए डेटा लाने के लिए आवश्यक होने पर तालिका चर का उपयोग किया जाता है। उदाहरण के लिए, कोड में एक क्वेरी है जो साइट के उपयोगकर्ताओं को लौटाती है। अब, आप सभी उपयोगकर्ताओं की आईडी एकत्र करते हैं, उन्हें तालिका चर में जोड़ते हैं और इन उपयोगकर्ताओं के लिए पते खोज सकते हैं। शायद, कोई पूछ सकता है कि हम डेटाबेस पर एक क्वेरी को निष्पादित क्यों नहीं करते हैं और सब कुछ तुरंत प्राप्त करते हैं? मेरे पास एक सरल उदाहरण है।
मान लें कि उपयोगकर्ता वेब सेवा से आते हैं, जबकि उनके पते आपके डेटाबेस में संग्रहीत हैं। इस मामले में, कोई रास्ता नहीं है। हमें सेवा से उपयोगकर्ता आईडी का एक गुच्छा मिला है, और डेटाबेस को क्वेरी करने से बचने के लिए, कोई यह तय करता है कि क्वेरी पैरामीटर में सभी आईडी को तालिका चर के रूप में जोड़ना आसान है और क्वेरी अच्छी तरह से दिखेगी:
उपयोगकर्ताओं के शामिल होने पर @t से *चुनें a.UserID=users.UserIDos. पर पता करें
यह सब सही काम करता है। C# कोड में, आप LINQ का उपयोग करके दोनों डेटा सरणियों के परिणामों को एक ऑब्जेक्ट में जल्दी से जोड़ सकते हैं। हालांकि, क्वेरी का प्रदर्शन प्रभावित हो सकता है।
तथ्य यह है कि तालिका चर बड़ी मात्रा में डेटा को संसाधित करने के लिए डिज़ाइन नहीं किए गए थे। यदि मैं गलत नहीं हूँ, तो क्वेरी ऑप्टिमाइज़र हमेशा LOOP निष्पादन विधि का उपयोग करेगा। इस प्रकार, @t से प्रत्येक आईडी के लिए, पता तालिका में एक खोज होगी। अगर @t में 1000 रिकॉर्ड हैं, तो सर्वर एड्रेस को 1000 बार स्कैन करेगा।
निष्पादन के संदर्भ में, स्कैन की पागल संख्या के कारण, सर्वर बस डेटा खोजने की कोशिश करना छोड़ देता है।
संपूर्ण पता तालिका को स्कैन करना और सभी उपयोगकर्ताओं को एक साथ ढूंढना अधिक प्रभावी है। इस विधि को मर्ज कहा जाता है। हालाँकि, बहुत सारे सॉर्ट किए गए डेटा होने पर SQL सर्वर इसे चुनता है। इस मामले में, ऑप्टिमाइज़र को यह नहीं पता होता है कि वेरिएबल में कितना और कौन सा डेटा जोड़ा जाएगा, और क्या सॉर्टिंग है क्योंकि इस तरह के वेरिएबल में इंडेक्स शामिल नहीं हैं।
यदि तालिका चर में बहुत कम डेटा है और आप इसमें हजारों पंक्तियाँ नहीं डालते हैं, तो सब कुछ ठीक है। हालांकि, यदि आप ऐसे चरों का उपयोग करना चाहते हैं और उनमें बड़ी मात्रा में डेटा जोड़ना चाहते हैं, तो आपको पढ़ना जारी रखना चाहिए।
यदि आप तालिका चर को SQL से बदल देते हैं, तो भी यह क्वेरी प्रदर्शन को बहुत तेज़ कर देगा:
से *से चुनें (उपयोगकर्ता आईडी संघ के रूप में 10377 का चयन करें सभी 73736 संघ का चयन करें 7474748 .... का चयन करें) जब उपयोगकर्ता पता a.UserID =users.UserID
इस तरह के हजारों सेलेक्ट स्टेटमेंट हो सकते हैं और क्वेरी टेक्स्ट बहुत बड़ा होगा, लेकिन इसे बड़ी मात्रा में डेटा के लिए हजारों गुना तेजी से निष्पादित किया जाएगा क्योंकि SQL सर्वर एक प्रभावी निष्पादन योजना चुन सकता है।
यह क्वेरी बहुत अच्छी नहीं लग रही है। हालांकि, इसकी निष्पादन योजना को कैश नहीं किया जा सकता क्योंकि केवल एक आईडी बदलने से संपूर्ण क्वेरी टेक्स्ट भी बदल जाएगा और पैरामीटर का उपयोग नहीं किया जा सकता है।
मुझे लगता है कि माइक्रोसॉफ्ट ने उपयोगकर्ताओं से इस तरह से सारणीबद्ध चर का उपयोग करने की उम्मीद नहीं की थी, लेकिन एक अच्छा समाधान है।
इस समस्या को हल करने के कई तरीके हैं। हालांकि, मेरी राय में, प्रदर्शन के मामले में सबसे प्रभावी विकल्प (RECOMPILE) को क्वेरी के अंत में जोड़ना है:
उपयोगकर्ताओं के शामिल होने पर *@t से चुनें।यह विकल्प ORDER BY के बाद भी एक बार क्वेरी के अंत में जोड़ा जाता है। इस विकल्प का उद्देश्य प्रत्येक निष्पादन पर SQL सर्वर को क्वेरी को पुन:संकलित करना है।
यदि हम उसके बाद क्वेरी के प्रदर्शन को मापते हैं, तो सबसे अधिक संभावना है कि खोज करने में लगने वाला समय कम हो जाएगा। बड़े डेटा के साथ, प्रदर्शन में सुधार दसियों मिनट से लेकर सेकंड तक महत्वपूर्ण हो सकता है। अब, सर्वर प्रत्येक क्वेरी को चलाने से पहले अपना कोड संकलित करता है और कैश से निष्पादन योजना का उपयोग नहीं करता है, लेकिन चर में डेटा की मात्रा के आधार पर एक नया उत्पन्न करता है, और यह आमतौर पर बहुत मदद करता है।
दोष यह है कि निष्पादन योजना संग्रहीत नहीं होती है और सर्वर को क्वेरी को संकलित करना होता है और हर बार एक प्रभावी निष्पादन योजना की तलाश करनी होती है। हालांकि, मैंने उन प्रश्नों को नहीं देखा है जहां इस प्रक्रिया में 100 एमएस से अधिक समय लगा।
क्या तालिका चर का उपयोग करना एक बुरा विचार है? नहीं ऐसा नहीं है। बस याद रखें कि वे बड़े डेटा के लिए नहीं बनाए गए थे। कभी-कभी, एक अस्थायी तालिका बनाना बेहतर होता है, यदि बहुत अधिक डेटा है, और इस तालिका में डेटा सम्मिलित करें, या यहां तक कि फ्लाई पर एक इंडेक्स भी बनाएं। मुझे यह रिपोर्ट के साथ करना था, हालांकि केवल एक बार। उस समय, मैंने एक रिपोर्ट तैयार करने का समय 3 घंटे से घटाकर 20 मिनट कर दिया था।
मैं इसे कई प्रश्नों में विभाजित करने और चर में परिणाम संग्रहीत करने के बजाय एक बड़ी क्वेरी का उपयोग करना पसंद करता हूं। SQL सर्वर को एक बड़ी क्वेरी के प्रदर्शन को ट्यून करने की अनुमति दें और यह आपको निराश नहीं करेगा। कृपया ध्यान दें कि आपको टेबल वेरिएबल्स का सहारा केवल चरम मामलों में ही लेना चाहिए जब आप वास्तव में उनके लाभ देखते हैं।