मेरे कार्यालय में, हमारे पास एक क्वेरी है जो बहुत बदसूरत है, लेकिन उत्पादन में और विकास के वातावरण (क्रमशः 20sec, और 4sec) में बहुत अच्छी तरह से चलती है। हालांकि हमारे परीक्षण वातावरण में यह 4hrs से अधिक समय लगता है। SQL2005 (+ नवीनतम पैच) उत्पादन और विकास में चल रहा है। SQL2008R2 परीक्षण में चल रहा है।
मैंने क्वेरी योजना पर एक नज़र डाली, और यह दिखाता है कि SQL2008R2 लिंक-सर्वर से लौटी पंक्तियों को संग्रहीत करने के लिए एक टेबल स्पूल (आलसी स्पूल) के माध्यम से TempDB का उपयोग कर रहा है। अगला चरण क्वेरी के 96.3% खाने के रूप में नेस्टेड लूप्स (बाएं एंटी सेमी जॉइन) दिखा रहा है। दोनों ऑपरेटरों के बीच की लाइन 5,398MB पर है!
SQL 2005 के लिए क्वेरी प्लान में tempdb का कोई उपयोग नहीं होता है और कोई वाम विरोधी अर्ध सम्मिलित होने का उपयोग नहीं करता है।
नीचे स्वच्छता कोड है और निष्पादन 2005 की योजना को शीर्ष पर, नीचे की ओर 2008R2 की योजना है।
क्या कारण है धीमा धीमा और परिवर्तन? मैं एक अलग निष्पादन योजना देखने की उम्मीद कर रहा था, ताकि मुझे परेशान न करें। क्वेरी समय में नाटकीय रूप से धीमा होना मुझे परेशान करता है।
क्या मुझे अंतर्निहित हार्डवेयर को देखना है, क्योंकि 2008R2 संस्करण tempdb का उपयोग कर रहा है, मुझे उस पर एक नज़र डालनी है कि इसका उपयोग कैसे अनुकूलित करें?
क्या क्वेरी लिखने का एक बेहतर तरीका है?
सहायता के लिए धन्यवाद।
INSERT INTO Table1_GroupLock (iGroupID, dLockedDate)
SELECT
Table1.iGroupID,
GETDATE()
FROM Table1
WHERE
NOT EXISTS (
SELECT 1
FROM LinkedServer.Database.Table2 Alias2
WHERE
(
Alias2.FirstName + Alias2.LastName = dbo.fnRemoveNonLetter(Table1.FullName)
AND NOT dbo.fnRemoveNonLetter(Table1.FullName) IS NULL
AND NOT Alias2.FirstName IS NULL
AND NOT Alias2.LastName IS NULL
) OR (
Alias2.FamilyName = dbo.fnRemoveNonLetter(Table1.FamilyName)
AND Alias2.Child1Name = dbo.fnRemoveNonLetter(Table1.Child1Name)
AND NOT dbo.fnRemoveNonLetter(Table1.FamilyName) IS NULL
AND NOT dbo.fnRemoveNonLetter(Table1.Child1Name) IS NULL
AND NOT Alias2.Familyname IS NULL
AND NOT Alias2.Child1Name IS NULL
) OR (
Alias2.StepFamilyName = dbo.fnRemoveNonLetter(Table1.StepFamilyName)
AND Alias2.StepFamilyNameChild1 = dbo.fnRemoveNonLetter(Table1.StepFamilyNameChild2)
AND NOT Alias2.StepFamilyName IS NULL
AND NOT Alias2.StepFamilyNameChild1 IS NULL
AND NOT dbo.fnRemoveNonLetter(Table1.StepFamilyName) IS NULL
AND NOT dbo.fnRemoveNonLetter(Table1.StepFamilyNameChild2) IS NULL
)
) AND NOT EXISTS (
SELECT 1
FROM Table3
INNER JOIN Table4
ON Table4.FirstNameType = Table3.FirstNameType
INNER JOIN table5
ON table5.LastNameType = Table3.LastNameType
WHERE
Table3.iGroupID = Table1.iGroupID
AND Table3.bIsClosed = 0
AND Table4.sNameTypeConstant = 'new_lastname'
AND table5.sFirstNameConstant = 'new_firstname'
)
:: EDIT :: क्वेरी को किसी भिन्न SQL2005 उदाहरण से निष्पादित किया गया है, जो कि "अच्छा एक" के समान निष्पादन योजना है। अभी भी यह सुनिश्चित नहीं है कि दो 2005 के संस्करण 2008R2 लिंक किए गए सर्वर से बेहतर कैसे चल रहे हैं, 2008R2 के उदाहरण 2008R2 के उदाहरणों की तुलना में।
हालांकि मैं इस बात से इनकार नहीं करता कि कोड कुछ काम का उपयोग कर सकता है, अगर यह कोड समस्या थी, तो क्या मैं अपने सभी परीक्षणों में समान योजनाएं नहीं देखूंगा? SQL संस्करण के बावजूद?
:: EDIT :: मैंने 2008R2 के दोनों उदाहरणों में SP1 और CU3 को लागू किया है, अभी भी कोई पासा नहीं है। मैंने विशेष रूप से लिंक किए गए सर्वर में कोलोकेशन सेट किया है, कोई पासा नहीं। मैंने विशेष रूप से अपने उपयोगकर्ता acct के दोनों उदाहरणों पर sysadmin होने की अनुमति निर्धारित की है, कोई पासा नहीं। मैंने अपने एसक्यूएल सर्वर 2008 के इंटर्नल और समस्या निवारण को भी याद किया है, हम देखेंगे कि क्या मैं इसे कैसे नीचे ट्रैक कर सकता हूं।
मदद और सुझावों के लिए सभी को धन्यवाद।
:: EDIT :: मैंने लिंक किए गए सर्वर में कई अनुमति परिवर्तन किए हैं। मैंने SQL लॉगिन, डोमेन लॉगिन का उपयोग किया है, मैंने उपयोगकर्ताओं को प्रतिरूपित किया है, मैंने "इस सुरक्षा संदर्भ का उपयोग करके बनाया" विकल्प का उपयोग किया है। मैंने लिंक किए गए सर्वर के दोनों किनारों पर उपयोगकर्ताओं को बनाया है जिनके सर्वर पर sysadmin अधिकार हैं। मुझे कोई विचार नहीं सूझ रहा।
मैं अभी भी जानना चाहूंगा कि SQL2005 क्वेरी को नाटकीय रूप से SQL2008R2 से अलग क्यों निष्पादित कर रहा है। यदि यह क्वेरी खराब थी, तो मुझे SQL2005 और SQL2008R2 दोनों पर 4 + घंटे का रन समय दिखाई देगा।