SQL 2005 बनाम SQL 2008R2 पर क्वेरी अलग-अलग चल रही है


9

मेरे कार्यालय में, हमारे पास एक क्वेरी है जो बहुत बदसूरत है, लेकिन उत्पादन में और विकास के वातावरण (क्रमशः 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'
 )

एसक्यूएल -2005


SQL2008R2

:: EDIT :: क्वेरी को किसी भिन्न SQL2005 उदाहरण से निष्पादित किया गया है, जो कि "अच्छा एक" के समान निष्पादन योजना है। अभी भी यह सुनिश्चित नहीं है कि दो 2005 के संस्करण 2008R2 लिंक किए गए सर्वर से बेहतर कैसे चल रहे हैं, 2008R2 के उदाहरण 2008R2 के उदाहरणों की तुलना में।

हालांकि मैं इस बात से इनकार नहीं करता कि कोड कुछ काम का उपयोग कर सकता है, अगर यह कोड समस्या थी, तो क्या मैं अपने सभी परीक्षणों में समान योजनाएं नहीं देखूंगा? SQL संस्करण के बावजूद?

:: EDIT :: मैंने 2008R2 के दोनों उदाहरणों में SP1 और CU3 को लागू किया है, अभी भी कोई पासा नहीं है। मैंने विशेष रूप से लिंक किए गए सर्वर में कोलोकेशन सेट किया है, कोई पासा नहीं। मैंने विशेष रूप से अपने उपयोगकर्ता acct के दोनों उदाहरणों पर sysadmin होने की अनुमति निर्धारित की है, कोई पासा नहीं। मैंने अपने एसक्यूएल सर्वर 2008 के इंटर्नल और समस्या निवारण को भी याद किया है, हम देखेंगे कि क्या मैं इसे कैसे नीचे ट्रैक कर सकता हूं।

मदद और सुझावों के लिए सभी को धन्यवाद।

:: EDIT :: मैंने लिंक किए गए सर्वर में कई अनुमति परिवर्तन किए हैं। मैंने SQL लॉगिन, डोमेन लॉगिन का उपयोग किया है, मैंने उपयोगकर्ताओं को प्रतिरूपित किया है, मैंने "इस सुरक्षा संदर्भ का उपयोग करके बनाया" विकल्प का उपयोग किया है। मैंने लिंक किए गए सर्वर के दोनों किनारों पर उपयोगकर्ताओं को बनाया है जिनके सर्वर पर sysadmin अधिकार हैं। मुझे कोई विचार नहीं सूझ रहा।

मैं अभी भी जानना चाहूंगा कि SQL2005 क्वेरी को नाटकीय रूप से SQL2008R2 से अलग क्यों निष्पादित कर रहा है। यदि यह क्वेरी खराब थी, तो मुझे SQL2005 और SQL2008R2 दोनों पर 4 + घंटे का रन समय दिखाई देगा।

जवाबों:


5

मैं चाहूंगा कि आप क्वेरी को फिर से काम करें।

आपके पास sargability समस्याएं हैं, और यहां तक ​​कि स्केलर फ़ंक्शन कॉल का उपयोग कर रहे हैं, जो क्वेरी को भी नुकसान पहुंचाएगा। आप Table2 पर एक FullName कंप्यूटेड कॉलम बनाना चाहते हैं और उस पर एक इंडेक्स डाल सकते हैं, जिससे आपका इंडेक्स INCLUDE फर्स्टनाम और लास्टनाम सुनिश्चित कर सकता है। आपको उन इंडेक्स को भी जोड़ना चाहिए जो दूसरे की मदद करते हैं

इसके अलावा, अपनी "RemoveNonLetter" कार्यक्षमता करने के लिए एक इनलाइन तालिका-मूल्यवान फ़ंक्शन करें, और उपयोग करने के लिए अपनी क्वेरी फिर से करें, शायद APPLY का उपयोग करते हुए जैसा कि मैंने यहां किया है।

और निश्चित रूप से उस बग की जांच करें जो पॉल के उत्तर को संदर्भित करता है।

INSERT INTO Table1_GroupLock (iGroupID, dLockedDate)
SELECT 
 Table1.iGroupID,
 GETDATE()
FROM Table1
OUTER APPLY (SELECT NonLettersRemoved FROM dbo.ifnRemoveNonLetter(Table1.FullName)) AS fn (FullName)
OUTER APPLY (SELECT NonLettersRemoved FROM dbo.ifnRemoveNonLetter(Table1.FamilyName)) AS famn (FamilyName)
OUTER APPLY (SELECT NonLettersRemoved FROM dbo.ifnRemoveNonLetter(Table1.Child1Name)) AS c1n (Child1Name)
OUTER APPLY (SELECT NonLettersRemoved FROM dbo.ifnRemoveNonLetter(Table1.StepFamilyName)) AS sfn (StepFamilyName)
OUTER APPLY (SELECT NonLettersRemoved FROM dbo.ifnRemoveNonLetter(Table1.StepFamilyNameChild2)) AS sfnc2 (StepFamilyNameChild2)
WHERE 
 NOT EXISTS (
  SELECT 1
  FROM LinkedServer.Database.Table2 Alias2
  WHERE Alias2.FullName = fn.FullName
  UNION ALL
  SELECT 1
  FROM LinkedServer.Database.Table2 Alias2
  WHERE Alias2.FamilyName = famn.FamilyName AND Alias2.Child1Name = c1n.Child1Name
  UNION ALL
  SELECT 1
  FROM LinkedServer.Database.Table2 Alias2
  WHERE Alias2.StepFamilyName = sfn.StepFamilyName AND Alias2.StepFamilyNameChild1 = sfnc2.StepFamilyNameChild2
 ) 
 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'
 )
;

6

पिछले उत्तरों को जोड़ते हुए, योजना प्रतिगमन का कारण ज्ञात कार्डिनैलिटी अनुमान बग के कारण हो सकता है जब योजना में एक एंटी सेमी जॉइन शामिल होता है। KB 2222998 देखें

2005 की योजना को स्वीकार्य प्रदर्शन मानते हुए, आप सर्वर को एक ऐसे संस्करण में ला सकते हैं जिसमें वह फिक्स शामिल है (और इसे सक्रिय करने के लिए TF4199 को सक्षम करना) आपको 'अच्छे' प्लान में लौटाएगा।

उस ने कहा, उस क्वेरी को सुधारने के लिए कई अन्य अवसर हैं, इसलिए इसके बजाय उस पर ध्यान केंद्रित करने का एक अच्छा समय हो सकता है।


5

मेरा सुझाव है कि दूरस्थ डेटा स्थानीय रूप से स्पूल किया जाता है क्योंकि इनमें से एक

  1. लिंक की गई सर्वर सेटिंग्स (जैसे टकराव) समान नहीं हैं
  2. लिंक की गई सर्वर सेटिंग्स के बावजूद, स्थानीय टकराव रिमोट के समान नहीं है
  3. अनुमतियों के कारण क्वेरी सही ढंग से दूरस्थ रूप से नहीं चल सकती

बिंदु 1 के लिए, sp_serveroption
और बिंदु 2 के लिए देखें , लेकिन सर्वर / DB collations की भी जाँच करें।

बिंदु 3 के लिए, इन्हें लिंची शीया से देखें:

आप SQL सर्वर को स्थानीय रूप से मेरे जवाब के अनुसार सभी डेटा संसाधित करने के लिए कह रहे हैं: एक दृश्य में OPENQUERY का उपयोग करने के प्रदर्शन निहितार्थ

संपादित करें

दूसरे नज़र में, मैं एक के बजाय "अच्छा" योजना पर 2 रिमोट कॉल देखता हूं। यह पुष्टि करता है कि मैं यहाँ क्या कह रहा हूँ


लंबी देरी के लिए क्षमा करें। 1: मैंने लिंक किए गए सर्वर सेटिंग्स की जाँच की, वे वही हैं 2: मैंने भी जाँच की और अंतर्निहित सर्वर संपत्तियों के टकराव को दूरस्थ सर्वर पर सेट किया। 3: सुरक्षा संदर्भ मैं अभी भी ए / बी परीक्षण करने पर काम कर रहा हूं। मैं अभी भी बहुत अलग-अलग निष्पादन योजनाओं के पीछे तर्क पर जोर दे रहा हूं। R2 सर्वर से R2 सर्वर तक यह केवल चुनिंदा (150K पंक्तियों में अच्छी तरह से खींच रहा है) चल रहा है, फिर जॉइन कर रहा है। जहां 2005 से R2 के रूप में यह चयन कर रहा है, और रिमोट सर्वर पर जुड़ता है। दोनों परिदृश्यों के लिए सुरक्षा संदर्भ समान हैं।
RateControl

3

+1 को अपनी क्वेरी टिप्पणी डेटागोड से पुनः प्रयास करें पर।

मुझे भी आश्चर्य हो रहा है कि क्या आप इस स्लोडाउन की वजह से जुड़े सर्वर साइड पर किसी परमिशन की समस्या से टकरा रहे हैं। मैं इस जुड़े सर्वर मंदी के बारे में कुछ समय पहले ब्लॉग किया था। हो सकता है कि परमिट की पुष्टि हो जाए (क्या यह SQL लिंक्ड सर्वर है? या क्या यह एक और DBMS है? यदि बाद वाला है, तो आपको वैसे भी महान आँकड़े नहीं मिलेंगे)

क्या आपके पास परीक्षण परिवेश पर SQL Server 2005 अभी भी इस क्वेरी को आज़माने और पर्यावरण पर नियंत्रण रखने के लिए है?

क्या आपने नवीनीकरण के बाद से आंकड़े बनाए हैं?


3

इस तुलना के साथ बहुत सारी समस्याएं हैं ... मुझे अभी पता नहीं है कि कहां से शुरू करना है।

  1. अपने उत्पादन और परीक्षण मशीनों के लिए सटीक चश्मा प्राप्त करें।

  2. दोनों वातावरण में विभिन्न लिंक किए गए severs के बीच नेटवर्क लिंक का निर्धारण करें। क्या वे एक ही गति हैं? क्या सर्वर दोनों वातावरणों में एक दूसरे के बगल में स्थित हैं?

  3. क्या कोई ऐसा तरीका है जिससे आप लिंक किए गए सर्वर का उपयोग न करने के लिए क्वेरी को फिर से लिख सकते हैं? सर्वरों में तालिकाओं में शामिल होने से आप टोपोलॉजी परिवर्तन के लिए कमजोर हो जाते हैं, और अधिकांश मामलों में उनकी बुरी तरह से धीमी गति से।

  4. NOT और OR का उपयोग आम तौर पर पूर्ण टेबल स्कैन की ओर जाता है। क्वेरी को पुन: लिखने का प्रयास करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.