दो पूरक कौशल हैं जो क्वेरी ट्यूनिंग में बहुत उपयोगी हैं। एक निष्पादन योजनाओं को पढ़ने और व्याख्या करने की क्षमता है। दूसरा इस बारे में थोड़ा जान रहा है कि क्वेरी ऑप्टिमाइज़र SQL टेक्स्ट को निष्पादन योजना में अनुवाद करने के लिए कैसे काम करता है। दो चीजों को एक साथ रखने से हमें उस समय का पता लगाने में मदद मिल सकती है जब एक अपेक्षित अनुकूलन लागू नहीं किया गया था, जिसके परिणामस्वरूप एक निष्पादन योजना उतनी कुशल नहीं है जितनी हो सकती है। SQL सर्वर किन ऑप्टिमाइज़ेशन को लागू कर सकता है (और किन परिस्थितियों में) दस्तावेज़ों की कमी का मतलब है कि इसमें से बहुत कुछ अनुभव के लिए नीचे आता है।
एक उदाहरण
इस आलेख के लिए नमूना क्वेरी कुछ महीने पहले SQL सर्वर MVP Fabiano Amorim द्वारा पूछे गए प्रश्न पर आधारित है, जो उनके सामने आई वास्तविक दुनिया की समस्या पर आधारित है। नीचे दी गई स्कीमा और परीक्षण क्वेरी वास्तविक स्थिति का सरलीकरण है, लेकिन यह सभी महत्वपूर्ण विशेषताओं को बरकरार रखती है।
तालिका dbo.T1 बनाएं (pk पूर्णांक प्राथमिक कुंजी, c1 पूर्णांक शून्य नहीं); तालिका dbo.T2 बनाएं (pk पूर्णांक प्राथमिक कुंजी, c1 पूर्णांक शून्य नहीं); तालिका dbo.T3 बनाएं (pk पूर्णांक प्राथमिक कुंजी, c1 पूर्णांक बनाएं) NOT NULL);GOCREATE INDEX NC1 on dbo.T1 (c1);CREATE INDEX nc1 on dbo.T2 (c1);CREATE INDEX nc1 on dbo.T3 (c1);GOCREATE VEEW dbo.V1AS चयन c1 dbo.T1 यूनियन से dbo से c1 चुनें।टेस्ट 1 - 10,000 पंक्तियां, SQL सर्वर 2005+
इन परीक्षणों के लिए विशिष्ट तालिका डेटा वास्तव में मायने नहीं रखता है। निम्नलिखित प्रश्न केवल तीन परीक्षण तालिकाओं में से प्रत्येक के लिए एक संख्या तालिका से 10,000 पंक्तियों को लोड करते हैं:
INSERT dbo.T1 (pk, c1) सेलेक्ट n, nFROM dbo.Numbers as NWHERE n 1 और 10000 के बीच; INSERT dbo.T2 (pk, c1) dbo.T1 से pk, c1 चुनें; INSERT dbo.T3 (pk, c1) चुनें pk, c1 dbo.T1 से;
डेटा लोड होने के साथ, परीक्षण क्वेरी के लिए तैयार की गई निष्पादन योजना है:
dbo.V1 से MAX(c1) चुनें;
यह निष्पादन योजना तार्किक SQL क्वेरी का एक बहुत ही प्रत्यक्ष कार्यान्वयन है (दृश्य संदर्भ V1 के विस्तार के बाद)। ऑप्टिमाइज़र क्वेरी को देखने के विस्तार के बाद देखता है, लगभग मानो क्वेरी को पूरी तरह से लिखा गया हो:
सेलेक्ट MAX(c1)फ्रॉम (सेलेक्ट c1 फ्रॉम dbo.T1 यूनियन सभी सिलेक्ट c1 फ्रॉम dbo.T2 यूनियन ऑल सिलेक्ट c1 फ्रॉम dbo.T3) AS V1;विस्तारित पाठ की निष्पादन योजना से तुलना करने पर, क्वेरी ऑप्टिमाइज़र के कार्यान्वयन की प्रत्यक्षता स्पष्ट है। बेस टेबल के प्रत्येक पढ़ने के लिए एक इंडेक्स स्कैन है,
UNION ALL
को लागू करने के लिए एक कॉन्सटेनेशन ऑपरेटर है। , और अंतिमMAX
. के लिए एक स्ट्रीम एग्रीगेट कुल।निष्पादन योजना गुण दर्शाते हैं कि लागत-आधारित अनुकूलन प्रारंभ किया गया था (अनुकूलन स्तर
FULL
है ), लेकिन यह जल्दी समाप्त हो गया क्योंकि एक 'काफी अच्छी' योजना मिली थी। चयनित योजना की अनुमानित लागत 0.1016240 . है जादू अनुकूलक इकाइयाँ।
टेस्ट 2 - 50,000 पंक्तियां, SQL Server 2008 और 2008 R2
परीक्षण परिवेश को 50,000 पंक्तियों के साथ चलाने के लिए रीसेट करने के लिए निम्न स्क्रिप्ट चलाएँ:
TRUNCATE TABLE dbo.T1;TRUNCATE TABLE dbo.T2;TRUNCATE TABLE dbo.T3; INSERT dbo.T1 (pk, c1) सेलेक्ट n, nFROM dbo.Numbers as NWHERE n 1 और 50000 के बीच; INSERT dbo.T2 (pk, c1) dbo.T1 से pk, c1 चुनें; INSERT dbo.T3 (pk, c1) dbo.T1 से pk, c1 चुनें; dbo.V1 से MAX(c1) चुनें;इस परीक्षण के लिए निष्पादन योजना आपके द्वारा चलाए जा रहे SQL सर्वर के संस्करण पर निर्भर करती है। SQL Server 2008 और 2008 R2 में, हमें निम्न योजना मिलती है:
योजना के गुण दिखाते हैं कि लागत-आधारित अनुकूलन अभी भी पहले की तरह उसी कारण से जल्दी समाप्त हो गया। अनुमानित लागत पहले की तुलना में 0.41375 . पर अधिक है इकाइयाँ लेकिन यह बेस टेबल की उच्च कार्डिनैलिटी के कारण अपेक्षित है।
टेस्ट 3 - 50,000 पंक्तियां, SQL सर्वर 2005 और 2012
2005 या 2012 में चलाई गई एक ही क्वेरी एक अलग निष्पादन योजना तैयार करती है:
अनुकूलन फिर से जल्दी समाप्त हो गया, लेकिन प्रति आधार तालिका 50,000 पंक्तियों के लिए अनुमानित योजना लागत कम होकर 0.0098585 हो गई है (0.41375 . से) SQL सर्वर 2008 और 2008 R2 पर)।
स्पष्टीकरण
जैसा कि आप जानते हैं, SQL सर्वर क्वेरी ऑप्टिमाइज़र अनुकूलन प्रयास को कई चरणों में अलग करता है, बाद के चरणों में अधिक अनुकूलन तकनीकों को जोड़कर और अधिक समय की अनुमति देता है। अनुकूलन चरण हैं:
- तुच्छ योजना
- लागत-आधारित अनुकूलन
- लेनदेन प्रसंस्करण (खोज 0)
- त्वरित योजना (खोज 1)
- समानांतरता सक्षम के साथ त्वरित योजना
- पूर्ण अनुकूलन (खोज 2)
यहां किए गए परीक्षणों में से कोई भी एक तुच्छ योजना के लिए योग्य नहीं है क्योंकि कुल और यूनियनों के पास कई कार्यान्वयन संभावनाएं हैं, जिनके लिए लागत-आधारित निर्णय की आवश्यकता होती है।
लेन-देन संसाधन
लेन-देन प्रसंस्करण (टीपी) चरण के लिए आवश्यक है कि एक क्वेरी में कम से कम तीन तालिका संदर्भ हों, अन्यथा लागत-आधारित अनुकूलन इस चरण को छोड़ देता है और सीधे त्वरित योजना पर चला जाता है। टीपी चरण का लक्ष्य ओएलटीपी वर्कलोड की कम लागत वाली नौवहन संबंधी पूछताछ है। यह सीमित संख्या में अनुकूलन तकनीकों की कोशिश करता है, और नेस्टेड लूप जॉइन के साथ योजनाओं को खोजने तक सीमित है (जब तक कि एक वैध योजना बनाने के लिए हैश जॉइन की आवश्यकता न हो)।
कुछ मामलों में यह आश्चर्यजनक है कि परीक्षण क्वेरी OLTP योजनाओं को खोजने के उद्देश्य से एक चरण के लिए योग्य है। हालांकि क्वेरी में आवश्यक तीन तालिका संदर्भ शामिल हैं, लेकिन इसमें कोई भी शामिल नहीं है। तीन टेबल की आवश्यकता सिर्फ एक अनुमानी है, इसलिए मैं इस बिंदु पर काम नहीं करूंगा।
कौन से ऑप्टिमाइज़र चरण चलाए गए?
संकलन से पहले और बाद में sys.dm_exec_query_optimizer_info की सामग्री की तुलना करने के लिए कई तरीके हैं, प्रलेखित। यह ठीक है, लेकिन यह इंस्टेंस-वाइड जानकारी रिकॉर्ड करता है, इसलिए आपको सावधान रहना होगा कि स्नैपशॉट के बीच होने वाला एकमात्र क्वेरी संकलन आपका ही है।
एक अनिर्दिष्ट (लेकिन उचित रूप से प्रसिद्ध) विकल्प जो SQL सर्वर के सभी वर्तमान समर्थित संस्करणों पर काम करता है, क्वेरी को संकलित करते समय ट्रेस फ़्लैग 8675 और 3604 को सक्षम करना है।
टेस्ट 1
यह परीक्षण निम्न के जैसा ट्रेस फ़्लैग 8675 आउटपुट उत्पन्न करता है:
टीपी चरण के बाद 0.101624 की अनुमानित लागत इतनी कम है कि अनुकूलक सस्ती योजनाओं की तलाश में नहीं जाता है। बेस टेबल की अपेक्षाकृत कम कार्डिनैलिटी को देखते हुए हम जिस सरल योजना के साथ समाप्त होते हैं, वह काफी उचित है, भले ही यह वास्तव में इष्टतम न हो।
टेस्ट 2
प्रत्येक आधार तालिका में 50,000 पंक्तियों के साथ, ट्रेस फ़्लैग अलग-अलग जानकारी दिखाता है:
इस बार, टीपी चरण के बाद अनुमानित लागत 0.428735 . है (अधिक पंक्तियाँ =उच्च लागत)। यह अनुकूलक को त्वरित योजना चरण में प्रोत्साहित करने के लिए पर्याप्त है। अधिक अनुकूलन तकनीकों के उपलब्ध होने से, इस चरण में 0.41375 . की लागत वाली एक योजना मिलती है . यह परीक्षण 1 योजना में एक बड़े सुधार का प्रतिनिधित्व नहीं करता है, लेकिन यह समानांतरवाद के लिए डिफ़ॉल्ट लागत सीमा से कम है, और पूर्ण अनुकूलन में प्रवेश करने के लिए पर्याप्त नहीं है, इसलिए फिर से अनुकूलन जल्दी समाप्त हो जाता है।
टेस्ट 3
SQL सर्वर 2005 और 2012 रन के लिए, ट्रेस फ़्लैग आउटपुट है:
संस्करणों के बीच चलने वाले कार्यों की संख्या में मामूली अंतर है, लेकिन महत्वपूर्ण अंतर यह है कि SQL सर्वर 2005 और 2012 पर, त्वरित योजना चरण केवल 0.0098543 की लागत वाली योजना ढूंढता है। इकाइयां यह वह योजना है जिसमें SQL Server 2008 और 2008 R2 योजनाओं में देखे गए Concatenation ऑपरेटर के नीचे तीन स्ट्रीम समुच्चय के बजाय शीर्ष ऑपरेटर शामिल हैं।
बग और अनिर्दिष्ट सुधार
SQL सर्वर 2008 और 2008 R2 में एक रिग्रेशन बग (2005 की तुलना में) है जो ट्रेस फ्लैग 4199 के तहत तय किया गया था, लेकिन जहां तक मैं कह सकता हूं दस्तावेज नहीं है। TF 4199 के लिए प्रलेखन है जो 4199 द्वारा कवर किए जाने से पहले अलग-अलग ट्रेस फ़्लैग्स के तहत उपलब्ध कराए गए फ़िक्सेस को सूचीबद्ध करता है, लेकिन जैसा कि नॉलेज बेस लेख कहता है:
<ब्लॉकक्वॉट>यह एक ट्रेस ध्वज उन सभी फ़िक्सेस को सक्षम करने के लिए उपयोग किया जा सकता है जो पहले कई ट्रेस फ़्लैग के अंतर्गत क्वेरी प्रोसेसर के लिए बनाए गए थे। इसके अतिरिक्त, इस ट्रेस फ्लैग का उपयोग करके भविष्य के सभी क्वेरी प्रोसेसर सुधारों को नियंत्रित किया जाएगा।
इस मामले में बग उन 'भविष्य के क्वेरी प्रोसेसर फिक्स' में से एक है। एक विशेष अनुकूलन नियम, ScalarGbAggToTop , परीक्षण 2 योजना में देखे गए नए योगों पर लागू नहीं होता है। SQL Server 2008 और 2008 R2 के उपयुक्त बिल्ड पर ट्रेस फ्लैग 4199 सक्षम होने के साथ, बग को ठीक किया गया है और परीक्षण 3 से इष्टतम योजना प्राप्त की गई है:
-- 2008 और 2008 R2SELECT MAX(c1) के लिए dbo.V1OPTION (QUERYTRACEON 4199) से ट्रेस फ्लैग 4199 आवश्यक है;
निष्कर्ष
एक बार जब आप जान जाते हैं कि अनुकूलक एक अदिश MIN
को रूपांतरित कर सकता है या MAX
एक TOP (1)
. के लिए कुल मिलाकर एक आदेशित स्ट्रीम पर, परीक्षण 2 में दिखाया गया प्लान अजीब लगता है। इंडेक्स स्कैन के ऊपर स्केलर समुच्चय (जो ऐसा करने के लिए कहे जाने पर ऑर्डर प्रदान कर सकता है) एक छूटे हुए अनुकूलन के रूप में सामने आता है जिसे सामान्य रूप से लागू किया जाएगा।
यही वह बिंदु है जिसे मैं परिचय में बना रहा था:एक बार जब आप यह महसूस कर लेते हैं कि अनुकूलक किस प्रकार की चीजें कर सकता है, तो यह उन मामलों को पहचानने में आपकी सहायता कर सकता है जहां कुछ गलत हो गया है।
उत्तर हमेशा ट्रेस फ्लैग 4199 को सक्षम करने के लिए नहीं होगा, क्योंकि आप उन मुद्दों पर आ सकते हैं जिन्हें अभी तक ठीक नहीं किया गया है। आप यह भी नहीं चाहेंगे कि ट्रेस फ़्लैग द्वारा कवर किए गए अन्य QP फ़िक्सेस किसी विशेष मामले में लागू हों - ऑप्टिमाइज़र फ़िक्सेस हमेशा चीजों को बेहतर नहीं बनाते हैं। यदि उन्होंने ऐसा किया, तो इस ध्वज का उपयोग करके दुर्भाग्यपूर्ण योजना प्रतिगमन से बचाने की कोई आवश्यकता नहीं होगी।
अन्य मामलों में समाधान अलग-अलग सिंटैक्स का उपयोग करके SQL क्वेरी को तैयार करना हो सकता है, क्वेरी को अधिक अनुकूलक-अनुकूल विखंडू में, या पूरी तरह से कुछ और तोड़ने के लिए। उत्तर जो भी हो, यह अभी भी अनुकूलक आंतरिक के बारे में कुछ जानने के लिए भुगतान करता है ताकि आप पहचान सकें कि पहली जगह में कोई समस्या थी :)