मेरे पास एक SQL सर्वर डेटाबेस है जहाँ क्वेरीज़ बहुत धीमी हैं, और बहुत से लॉकिंग और ब्लॉकिंग हैं।
जब मैं लापता सूचकांक DMV और क्वेरी योजनाओं को देखता हूं, तो कोई सुझाव नहीं हैं।
ऐसा क्यों है?
मेरे पास एक SQL सर्वर डेटाबेस है जहाँ क्वेरीज़ बहुत धीमी हैं, और बहुत से लॉकिंग और ब्लॉकिंग हैं।
जब मैं लापता सूचकांक DMV और क्वेरी योजनाओं को देखता हूं, तो कोई सुझाव नहीं हैं।
ऐसा क्यों है?
जवाबों:
हम कुछ कारणों को अधिक विस्तार से देखेंगे, और कुछ सामान्य सीमाओं के बारे में भी बात करेंगे।
सबसे पहले, लापता अनुक्रमणिका की सीमाएं :
- यह एक सूचकांक में उपयोग किए जाने वाले स्तंभों के लिए एक आदेश निर्दिष्ट नहीं करता है।
जैसा कि इस प्रश्नोत्तर में उल्लेख किया गया है: SQL सर्वर लापता सूचकांक अनुरोधों में प्रमुख स्तंभ क्रम कैसे निर्धारित करता है? सूचकांक परिभाषा में स्तंभों के क्रम को समानता बनाम असमानता के अनुसार निर्धारित किया जाता है, और फिर तालिका में स्तंभों की स्थिति।
चयनात्मकता पर कोई अनुमान नहीं हैं, और एक बेहतर आदेश उपलब्ध हो सकता है। यह पता लगाना आपका काम है।
विशेष सूचकांक
अनुक्रमणिका अनुरोध भी 'विशेष' अनुक्रमणिका को कवर नहीं करते, जैसे:
परिणामों को फ़िल्टर करने के लिए उपयोग किए जाने वाले स्तंभों से गुम अनुक्रमणिका कुंजी कॉलम बनाए जाते हैं, जैसे:
अनुक्रमणिका में शामिल किए गए स्तंभ क्वेरी द्वारा आवश्यक स्तंभों से उत्पन्न होते हैं, जैसे:
भले ही अक्सर, आपके द्वारा आदेशित या समूहित किए जाने वाले कॉलम प्रमुख कॉलम के रूप में फायदेमंद हो सकते हैं। यह एक सीमा तक वापस जाता है:
- यह एक अनुक्रमण विन्यास को ठीक करने का इरादा नहीं है।
उदाहरण के लिए, यह क्वेरी अनुपलब्ध अनुक्रमणिका अनुरोध को पंजीकृत नहीं करेगी, हालांकि LastAccessDate पर अनुक्रमणिका जोड़ने से क्रमबद्ध (और डिस्क पर फैल) की आवश्यकता को रोका जा सकेगा।
SELECT TOP (1000) u.DisplayName
FROM dbo.Users AS u
ORDER BY u.LastAccessDate DESC;
न ही स्थान पर इस समूहीकरण क्वेरी है।
SELECT TOP (20000) u.Location
FROM dbo.Users AS u
GROUP BY u.Location
खैर, हाँ, लेकिन यह कुछ भी नहीं से बेहतर है। रोते हुए बच्चे की तरह अनुक्रमणिका अनुरोधों के बारे में सोचें। आप जानते हैं कि एक समस्या है, लेकिन यह एक वयस्क के रूप में आप पर निर्भर करता है कि वह समस्या क्या है।
आराम करो, बालो। हम वहाँ पहुँच रहे हैं।
यदि आप TF 2330 सक्षम करते हैं , तो अनुपलब्ध अनुक्रमणिका अनुरोध लॉग नहीं होंगे। यह पता लगाने के लिए कि क्या आपके पास यह सक्षम है, इसे चलाएं:
DBCC TRACESTATUS;
अनुक्रमणिका अनुक्रमणिका अनुपलब्ध अनुक्रमणिका अनुरोध को हटा देगा। तो इससे पहले कि आप हाय-हो-सिल्वर-अवे, हर इंडेक्स को फिर से बनाए, विखंडन के दूसरे एक आईओटीए में बात करता है, उस जानकारी के बारे में सोचें जो आप हर बार जब आप कर रहे हैं, तो इसे साफ कर रहे हैं।
आप इस बारे में भी सोचना चाह सकते हैं कि आपकी अनुक्रमणिका को डीफ़्रैग्मेन्ट करने में मदद क्यों नहीं की जा रही है , वैसे भी। जब तक आप Columnstore का उपयोग नहीं कर रहे हैं ।
अनुक्रमणिका को जोड़ना, हटाना, या अक्षम करना उस तालिका के सभी अनुपलब्ध अनुक्रमणिका अनुरोधों को साफ कर देगा। यदि आप एक ही टेबल पर कई इंडेक्स बदलावों के माध्यम से काम कर रहे हैं, तो सुनिश्चित करें कि आप किसी भी बनाने से पहले उन सभी को स्क्रिप्ट कर लें।
यदि कोई योजना पर्याप्त सरल है, और सूचकांक पहुंच विकल्प पर्याप्त स्पष्ट है, और लागत काफी कम है, तो आपको एक तुच्छ योजना मिलेगी।
इसका प्रभावी मतलब यह है कि अनुकूलन करने वाले के लिए लागत आधारित निर्णय नहीं थे।
वाया पॉल व्हाइट :
त्रिविम योजना से किस प्रकार के क्वेरी का लाभ बार-बार बदल सकता है, लेकिन इसमें शामिल होने, उपशमन और असमानता जैसी चीजें आम तौर पर इस अनुकूलन को रोकती हैं।
जब कोई योजना तुच्छ होती है, तो अतिरिक्त अनुकूलन चरणों की खोज नहीं की जाती है, और लापता अनुक्रमणिका का अनुरोध नहीं किया जाता है ।
इन प्रश्नों और उनकी योजनाओं के बीच अंतर देखें :
SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2;
SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2
AND 1 = (SELECT 1);
पहली योजना तुच्छ है, और कोई अनुरोध नहीं दिखाया गया है। ऐसे मामले हो सकते हैं जहां बग्स गायब अनुक्रमणिकाओं को क्वेरी योजनाओं में दिखाई देने से रोकते हैं; वे आमतौर पर लापता सूचकांक डीएमवी में अधिक विश्वसनीय रूप से लॉग इन होते हैं, हालांकि।
भविष्यवाणी करता है कि जहां एक सूचकांक के साथ भी ऑप्टिमाइज़र एक सूचकांक का कुशलतापूर्वक उपयोग करने में सक्षम नहीं होगा, भले ही उन्हें लॉग होने से रोक सकता है।
चीजें जो आम तौर पर SARGable नहीं होती हैं:
SELECT *
FROM dbo.Users AS u
WHERE ISNULL(u.Age, 1000) > 1000;
SELECT *
FROM dbo.Users AS u
WHERE DATEDIFF(DAY, u.CreationDate, u.LastAccessDate) > 5000
SELECT *
FROM dbo.Users AS u
WHERE u.UpVotes + u.DownVotes > 10000000
DECLARE @ThisWillHappenWithStoredProcedureParametersToo NVARCHAR(40) = N'Eggs McLaren'
SELECT *
FROM dbo.Users AS u
WHERE u.DisplayName LIKE @ThisWillHappenWithStoredProcedureParametersToo
OR @ThisWillHappenWithStoredProcedureParametersToo IS NULL;
इन प्रश्नों में से कोई भी लापता सूचकांक अनुरोधों को दर्ज नहीं करेगा। इन पर अधिक जानकारी के लिए, निम्नलिखित लिंक देखें:
इस सूचकांक को लें:
CREATE INDEX ix_whatever ON dbo.Posts(CreationDate, Score) INCLUDE(OwnerUserId);
यह इस प्रश्न के लिए ठीक है:
SELECT p.OwnerUserId, p.Score
FROM dbo.Posts AS p
WHERE p.CreationDate >= '20070101'
AND p.CreationDate < '20181231'
AND p.Score >= 25000
AND 1 = (SELECT 1)
ORDER BY p.Score DESC;
योजना एक साधारण सीक ...
लेकिन चूँकि प्रमुख कुंजी स्तंभ कम-चयनात्मक विधेय के लिए है, इसलिए हमें उससे अधिक काम करना चाहिए:
तालिका 'पोस्ट'। स्कैन गिनती 13, तार्किक 136890 पढ़ता है
यदि हम इंडेक्स कुंजी कॉलम ऑर्डर बदलते हैं, तो हम बहुत कम काम करते हैं:
CREATE INDEX ix_whatever ON dbo.Posts(Score, CreationDate) INCLUDE(OwnerUserId);
और काफी कम पढ़ता है:
तालिका 'पोस्ट'। स्कैन गिनती 1, तार्किक 5 पढ़ता है
कुछ मामलों में, एसक्यूएल सर्वर एक इंडेक्स स्पूल के माध्यम से मक्खी पर एक इंडेक्स बनाने का चयन करेगा। जब एक सूचकांक स्पूल मौजूद होता है, तो एक लापता इंडेक्स अनुरोध नहीं होगा। निश्चित रूप से अपने आप सूचकांक को जोड़ना एक अच्छा विचार हो सकता है, लेकिन यह पता लगाने में आपकी मदद करने वाले SQL सर्वर पर भरोसा नहीं है।