SQL सर्वर को लगभग 30 वर्षों से अधिक हो गया है, और मैं लगभग लंबे समय से SQL सर्वर के साथ काम कर रहा हूँ। Kalen SQL सर्वर इंटर्नल के भाग एक में स्कैन को कवर करता है:समस्याग्रस्त ऑपरेटर।
मैंने इस अविश्वसनीय उत्पाद के वर्षों (और दशकों!) और संस्करणों में बहुत सारे बदलाव देखे हैं। इन पोस्ट में मैं आपके साथ साझा करूँगा कि मैं SQL सर्वर की कुछ विशेषताओं या पहलुओं को कैसे देखता हूँ, कभी-कभी कुछ ऐतिहासिक परिप्रेक्ष्य के साथ।
अपने SQL सर्वर प्रश्नों को ट्यून करना बेहतर प्रदर्शन और SQL सर्वर डायग्नोस्टिक्स के अनुकूलन के लिए सबसे अच्छी चीजों में से एक है। लेकिन ट्यूनिंग एक बहुत बड़ा विषय है! यह जानने के लिए कि सर्वोत्तम संभव तरीके से कैसे ट्यून किया जाए, न केवल आपके डेटा और आपके कार्यभार का संपूर्ण ज्ञान आवश्यक है, बल्कि यह ज्ञान भी है कि SQL सर्वर वास्तव में अपनी योजना निष्पादन विकल्प कैसे बनाता है। तो, यदि आप SQL सर्वर इंटर्नल के विशेषज्ञ नहीं हैं तो आप क्या कर सकते हैं? एक चीज जो आप कर सकते हैं, वह है उन लोगों पर भरोसा करना जो विशेषज्ञ हैं, साथ ही विशेषज्ञों द्वारा लिखे गए उपकरण भी। क्वेस्ट स्पॉटलाइट क्लाउड ट्यूनिंग पैक जैसे टूल आपको बेहतर क्वेरी प्रदर्शन के लिए सड़क पर आरंभ करने के लिए कुछ बेहतरीन सुझाव दे सकते हैं। बेशक, कोई भी बाहरी उपकरण आपके डेटा और आपके सभी कार्यभार के सभी विवरणों को नहीं जानता है, इसलिए आपके द्वारा लागू किए जाने वाले किसी भी सुझाव के गहन परीक्षण की हमेशा अनुशंसा की जाती है।
समस्याग्रस्त ऑपरेटरों पर इन पोस्टों में, मैं मान लूंगा कि आपको SQL सर्वर अनुक्रमणिका संरचनाओं का कुछ बुनियादी ज्ञान है। यहां कुछ जानकारी दी गई है जो सहायक होगी:
- बिना संकुल अनुक्रमणिका वाली तालिका को हीप कहा जाता है और इसमें कोई क्रम नहीं होता है। कोई पहली पंक्ति या अंतिम पंक्ति नहीं है। ढेर बिना किसी विशेष क्रम में पंक्तियों का एक गुच्छा है।
- क्लस्टर इंडेक्स का लीफ लेवल टेबल ही होता है। (यह तालिका की एक प्रति नहीं है, यह तालिका है।) सूचकांक की पंक्तियों को तार्किक रूप से क्रमबद्ध किया जाता है, जिसे क्लस्टर इंडेक्स कुंजी के रूप में परिभाषित किया गया था।
- गैर-संकुल सूचकांक के लीफ स्तर में तालिका की प्रत्येक पंक्ति के लिए एक अनुक्रमणिका पंक्ति होती है। पंक्तियों में गैर-संकुल कुंजी स्तंभ होते हैं और तार्किक रूप से उस क्रम में क्रमबद्ध होते हैं जिस क्रम में कुंजियाँ निर्दिष्ट की जाती हैं। कुंजी स्तंभों के अलावा, गैर-संकुल अनुक्रमणिका पंक्तियों में एक 'बुकमार्क' होता है जो तालिका में संदर्भित पंक्ति की ओर इशारा करता है। बुकमार्क दो रूपों में से एक में हो सकता है:
- यदि तालिका में संकुल अनुक्रमणिका है, तो बुकमार्क संकुल अनुक्रमणिका कुंजी है। (यदि संकुल अनुक्रमणिका कुंजी गैर संकुल अनुक्रमणिका कुंजी का भाग है, तो इसे दोहराया नहीं जाएगा।)
- यदि तालिका एक ढेर है, तो बुकमार्क एक पंक्ति आईडी या RID है, जो पंक्ति के भौतिक स्थान को निर्दिष्ट करता है। स्थान को आमतौर पर FileNum:PageNum:RowNum . के रूप में निर्दिष्ट किया जाता है ।
SQL सर्वर के अपने उपकरण क्वेरी निष्पादन योजना को देखने के लिए कई तरीके प्रदान करते हैं जिसे ऑप्टिमाइज़र ने किसी विशेष क्वेरी के लिए उपयोग करने का निर्णय लिया है। क्वेस्ट स्पॉटलाइट ट्यूनिंग पैक के अतिरिक्त, आप अपनी योजनाओं के बारे में और भी अधिक जानकारी प्राप्त कर सकते हैं।
निम्न कोड AdventureWorks . में दो तालिकाओं की प्रतियां बनाता है डेटाबेस (मैं AdventureWorks2016 . का उपयोग कर रहा हूँ , लेकिन आप दूसरे संस्करण का उपयोग कर सकते हैं)।
USE AdventureWorks2016;
GO
DROP TABLE IF EXISTS SalesHeader;
GO
SELECT *
INTO SalesHeader
FROM Sales.SalesOrderHeader;
GO
DROP TABLE IF EXISTS SalesDetail;
GO
SELECT * INTO SalesDetail
FROM Sales.SalesOrderDetail;
GO
"वास्तविक निष्पादन योजना शामिल करें" चालू करने के बाद अब एक क्वेरी निष्पादित करें जो दो तालिकाओं को एक साथ जोड़ती है
SELECT h.SalesOrderID, OrderDate, ProductID, UnitPrice, OrderQty
FROM SalesHeader h JOIN SalesDetail d
ON h.SalesOrderID = d.SalesOrderID
WHERE SalesOrderDetailID < 100;
GO
क्वेस्ट स्पॉटलाइट ट्यूनिंग पैक क्वेरी के साथ एक समस्या की रिपोर्ट करेगा, इसलिए आप "विश्लेषण देखें" पर क्लिक कर सकते हैं और "निष्पादन योजना" विकल्प चुन सकते हैं। आपको निम्नलिखित देखना चाहिए:
टेबल स्कैन को समझना
सबसे पहले, मैं एक अंग पर बाहर जाना चाहता हूं और कहता हूं कि कोई भी योजना संचालक नहीं है जो हमेशा खराब हो! यदि अनुकूलक खराब था तो इसे आपकी क्वेरी योजना में क्यों जोड़ देगा? यह संकेत दे सकता है कि आपके डेटा या अनुक्रमणिका संरचनाओं में सुधार की गुंजाइश है, लेकिन यह अपने आप में बुरा नहीं है।
ऊपर के उदाहरण में, ट्यूनिंग पैक टेबल स्कैन को स्पॉटलाइट कर रहा है, यह दर्शाता है कि वे समस्याग्रस्त हो सकते हैं। लेकिन यह हमेशा सच नहीं होता है कि टेबल स्कैन समस्याग्रस्त हैं। एक गैर-अनुक्रमित अनुक्रमणिका का उपयोग करने के लिए एक और भी बदतर स्थिति तालिका में प्रत्येक पंक्ति तक पहुंचने वाली क्वेरी की तलाश में होगी। इस विशेष प्रश्न के लिए, मैं सहमत हूँ कि स्कैन एक अच्छी बात नहीं हो सकती है क्योंकि हम केवल SalesDetail में कुछ पंक्तियों में रुचि रखते हैं तालिका (121,317 पंक्तियों में से 99, या प्रतिशत के दसवें हिस्से से कम।)
इसलिए, हम इंडेक्स बनाने के लिए विश्लेषण फलक में सुझावों को देख सकते हैं। बिक्री विवरण . के लिए सुझाव तालिका SalesOrderID . पर एक गैर-संकुल अनुक्रमणिका बनाने के लिए है कॉलम (जॉइन क्लॉज में कॉलम) और तालिका में हर दूसरे कॉलम को शामिल करें जो क्वेरी द्वारा लौटाया गया है। SalesHeader . के लिए सुझाव तालिका SalesOrderDetailId . पर एक गैर-संकुल अनुक्रमणिका है कॉलम, जो WHERE क्लॉज में कॉलम है, और ऑर्डरडेट को शामिल करें कॉलम, जो इस तालिका से लौटाया गया एकमात्र अन्य कॉलम है।
क्या होगा अगर हमारी क्वेरी थोड़ी अलग थी? क्या होगा यदि मैंने एक विशिष्ट कॉलम सूची के बजाय SELECT * का उपयोग करके यह क्वेरी चलाई थी। यदि आप इसे आजमाते हैं, और सिफारिशों को देखते हैं, तो यह एकल कुंजी कॉलम के अलावा तालिका में प्रत्येक कॉलम के लिए INCLUDE का उपयोग करने का सुझाव देता है। हालांकि इस तरह की अनुक्रमणिका इस विशेष क्वेरी को थोड़ा तेज़ चला सकती है, लेकिन यह अन्य प्रश्नों को धीमा कर सकती है, विशेष रूप से आपके अद्यतन प्रश्नों को धीमा कर सकती है। यह इंडेक्स मूल रूप से टेबल की एक कॉपी है, क्योंकि इंडेक्स के लीफ लेवल में टेबल का हर एक कॉलम होगा। यदि आप इस तरह की अनुशंसाएँ देखते हैं, तो एक इंडेक्स का सुझाव देते हुए जिसमें तालिका के सभी कॉलम शामिल हैं, मैं निश्चित रूप से थोड़ा पीछे हटने की सलाह देता हूँ और आँख बंद करके इसे बनाने की नहीं।
आपके SQL सर्वर निदान के लिए क्वेरी ट्यूनिंग में न केवल अनुक्रमणिका प्रबंधित करना शामिल है, बल्कि स्वयं प्रश्नों का प्रबंधन भी शामिल है। इस विशेष क्वेरी के लिए, हम वास्तव में तालिका में प्रत्येक पंक्ति को वापस करने के लिए SELECT * का उपयोग नहीं करने के लिए क्वेरी को फिर से लिखने से बेहतर हो सकते हैं। कॉलम का केवल एक छोटा सा उपसमूह लौटाना पर्याप्त हो सकता है, और फिर पहले उदाहरण की तरह एक बहुत छोटा सूचकांक पर्याप्त होगा।
क्या इनमें से कोई भी अनुक्रमणिका वास्तव में बनाने के लिए एक अच्छी अनुक्रमणिका होगी? संकुचित सूचकांक समग्र रूप से छोटा होगा और डेटा के अपडेट से कम प्रभावित होगा। सभी स्तंभों पर एक अनुक्रमणिका तालिका की दूसरी प्रति की तरह होती है, जिसे तालिका से भिन्न क्रम में क्रमबद्ध किया जाता है। ऐसी स्थितियां हैं जहां एक अलग क्रम में तालिका की 'दूसरी प्रति' उपयोगी हो सकती है, लेकिन डेटा संशोधन कार्यों के लिए बहुत अधिक ओवरहेड होगा। एक प्रतिनिधि कार्यभार के साथ एक परीक्षण प्रणाली पर सिफारिशों को आज़माने के लिए यह सुनिश्चित करने का एकमात्र तरीका है। केवल आप ही अपना डेटा और अपने प्रश्नों को जानते हैं, इसलिए इसे आज़माएं और देखें!
इंडेक्स स्कैन को समझना
जैसा कि मैंने ऊपर उल्लेख किया है, टेबल स्कैन हमेशा एक बुरी चीज नहीं होते हैं। लेकिन इंडेक्स स्कैन के बारे में क्या? क्योंकि क्लस्टर इंडेक्स लीफ लेवल टेबल ही होता है, क्लस्टर्ड इंडेक्स स्कैन टेबल स्कैन के समान होता है! यदि टेबल स्कैन खराब है, तो क्लस्टर्ड इंडेक्स स्कैन उतना ही खराब है। लेकिन यह हमेशा बुरा नहीं होता है। दोबारा, आपको इसे अपने सिस्टम पर परीक्षण करने की आवश्यकता है।
क्वेस्ट स्पॉटलाइट ट्यूनिंग पैक SQL सर्वर इंजन की अनुशंसाओं से पता चलता है कि आप कभी भी क्लस्टर इंडेक्स का सुझाव नहीं देते हैं। यह एक गैर-संकुल का सुझाव दे सकता है जिसमें तालिका में प्रत्येक कॉलम शामिल है (जैसा कि पहले उल्लेख किया गया है), जो कि तालिका का सिर्फ एक डुप्लिकेट है। अपने क्लस्टर इंडेक्स के लिए सबसे अच्छे कॉलम या कॉलम का पता लगाना अपने आप में एक बड़ा विषय है, इसलिए मैं यहाँ उस पर नहीं जाऊँगा।
एक तलाश क्या है? किसी योजना में एक सीक ऑपरेशन का अर्थ है कि SQL सर्वर एक पंक्ति, पंक्तियों का एक सेट, या पंक्तियों की एक श्रृंखला में प्रारंभिक और/या रोक बिंदु खोजने के लिए इंडेक्स ट्री में ऑर्डर किए गए डेटा का उपयोग कर रहा है। सामान्य तौर पर, यदि आप किसी तालिका से पंक्तियों का बहुत छोटा प्रतिशत लौटा रहे हैं, तो गैर-संकुल अनुक्रमणिका खोज का उपयोग करना एक पूरी तरह से उचित संचालन है। लेकिन एक क्वेरी के लिए एक खोज एक अच्छा विकल्प नहीं है जो एक तालिका से बहुत सारी पंक्तियों को वापस कर रहा है। लॉट कितने हैं? कोई सरल उत्तर नहीं है, लेकिन यदि आपकी क्वेरी कुछ प्रतिशत से अधिक पंक्तियों को वापस कर रही है, तो आपको यह सुनिश्चित करना चाहिए कि आपने अनुक्रमणिका सुझावों का अच्छी तरह से परीक्षण किया है। कभी-कभी एक टेबल स्कैन, या क्लस्टर्ड इंडेक्स स्कैन, इंडेक्स की तलाश से बेहतर होता है। (ऐसे ही एक उदाहरण के लिए, मेरी ब्लॉग पोस्ट यहाँ देखें)।
क्वेस्ट स्पॉटलाइट ट्यूनिंग पैक . जैसे टूल SQL सर्वर डायग्नोस्टिक्स के साथ अपनी ट्यूनिंग यात्रा शुरू करने के लिए आपको बहुत अच्छे सुझाव दे सकते हैं, लेकिन जितना अधिक आप SQL सर्वर इंडेक्स और SQL सर्वर ऑप्टिमाइज़र के काम करने के बारे में जानते हैं, उतना ही बेहतर होगा कि आप अपने प्रश्नों के लिए उन सुझावों का मूल्यांकन करने में सक्षम होंगे। डेटा, और संभवतः अपने सुझाव भी दे सकते हैं।
इस श्रृंखला में निम्नलिखित पोस्ट में, मैं आपको अन्य समस्याग्रस्त ऑपरेटरों के बारे में बताऊंगा जो आपकी क्वेरी योजनाओं में दिखाई दे सकते हैं, इसलिए जल्द ही वापस जांचें!