2011-08-15 8 views
7

मेरे पास एक विशेष SQL क्वेरी है जो एक रहस्यमय प्रदर्शन समस्या से पीड़ित है। क्वेरी है:कुल कार्यों का उपयोग कर SQL क्वेरी के प्रदर्शन में सुधार करने की आवश्यकता

SELECT COUNT(LengthOfTime) AS TotalTime, 
     SUM(LengthOfTime) AS TotalLength, 
     SUM(LengthOfTime)/COUNT(LengthOfTime) AS AverageTime, 
     SUM(Pops)/COUNT(LengthOfTime) AS AveragePop 
    FROM ((SELECT * 
      FROM (SELECT *, ID & YearRec AS ID2 
        FROM MyFirstTable 
       UNION ALL 
       SELECT *, ID & YearRec AS ID2 
        FROM Table2011) AS TEMP 
      WHERE STARTTIME >= '8/1/2011 00:00:00' 
      AND StartTime <= '8/5/2011 23:59:59') AS TEMP2 
    JOIN AppleTable ON TEMP2.Reason = AppleTable.Skills) 
    JOIN PeopleTable ON TEMP2.Operator = PeopleTable.Operators 
WHERE AppleTable.[ON] = 1 
    AND PeopleTable.[ON] = 1 
    AND Rec_Type = 'SECRET AGENT' 

यहां मुद्दा यह है कि इस क्वेरी (0:02 करने के लिए 0:00) बहुत जल्दी चलता है जब एक 5 दिन अवधि के लिए चलाते हैं, लेकिन बहुत धीरे धीरे (1:20 1:45 करने के लिए है) एक 6 दिन की अवधि के लिए।

टेबल्स (MyFirstTable और Table2011) में प्रति दिन लगभग 105,000 रिकॉर्ड हैं।

मेरा प्रश्न: वहाँ पंक्तियों की संख्या इससे पहले कि आप एसक्यूएल सर्वर में एक गंभीर प्रदर्शन समस्या का हल नहीं आप एक समग्र समारोह पारित कर सकते हैं करने के लिए एक ऊपरी सीमा है? (वर्तमान में 2008 आर 2 का उपयोग कर)

+0

क्या आपके आंकड़े अद्यतित हैं, क्या आपने हाल ही में इंडेक्स का पुनर्निर्माण किया है? –

+0

लगता है जैसे आप किसी मेमोरी ऑपरेशन से डिस्क की आवश्यकता वाले किसी व्यक्ति से बहते जा रहे हैं। मैं MySQL ट्यूनिंग विवरण से परिचित नहीं हूं, लेकिन अगर अस्थायी वर्कस्पेस के लिए मेमोरी आवंटन पैरामीटर है, तो आप इसे बढ़ाने का प्रयास कर सकते हैं। –

+1

@Jim: यह mySQL नहीं है ... –

उत्तर

4

नहीं, कुल कार्यों के लिए पूर्व निर्धारित परिभाषा नहीं है।

  • पुराने और/या अनुपयुक्त सूचकांक संरचना
  • कैश्ड कार्य योजना लागू करके
  • संचित डेटा
  • डेटा आकार नहीं किया जा रहा:

    प्रदर्शन में तिरछा संभावना से एक या निम्नलिखित कई से प्रभावित होता है वर्दी (पहले पांच दिन 10 पंक्तियां हैं जबकि छठी 100 बी पंक्तियां हैं)

आप क्वेरी चला सकते हैं एसएसएमएस में और वास्तविक निष्पादन योजना देखें। यह आपको उन स्थानों को बताएगा जहां क्वेरी चलाने की लागत सबसे अधिक है, और इससे आपको कार्यवाही का सर्वोत्तम तरीका निर्धारित करने में मदद मिलेगी।

संपादित करें टिप्पणी के आधार पर:

अगर वहाँ कि [STARTTIME] शामिल Table2011 पर एक सूचकांक नहीं है, तो एक बनाएँ। यदि कोई अनुक्रमणिका है, लेकिन इसे अनदेखा किया जा रहा है, तो आपको यह पता लगाना होगा कि क्यों। अगर खंडित किया गया है, तो सूचकांक का पुनर्निर्माण निश्चित रूप से मदद करेगा। वस्तु ब्राउज़र में विशिष्ट सूचकांक करने के लिए ब्राउज़ करें, राइट क्लिक करें और फिर से बनाना - यहाँ के पुनर्निर्माण के लिए कैसे

ALTER INDEX [YourIndexName] ON [dbo].[Table2011] REBUILD WITH (STATISTICS_NORECOMPUTE = ON);

वैकल्पिक रूप से आप SSMS में ऐसा कर सकते हैं है।

+0

मैंने वास्तविक निष्पादन योजना को देखा। तालिका2011 पर "तालिका स्कैन" से लागत का 9 7% आ रहा है। यूनियन – dan042988

+0

@ dan042988 उत्तर –

+0

से पहले स्टार्टटाइम की भविष्यवाणी करने के बाद मैंने सही दिशा में मुझे इंगित करने के लिए धन्यवाद। मैं एक नया सूचकांक बनाने के लिए वास्तविक निष्पादन योजना का उपयोग कर समाप्त हो गया 'उपयोग [DatabaseName] GO बनाएं nonclustered अनुक्रमणिका [QueryIndex1] पर [dbo]। [Table2011] ([Rec_Type], [StartTime]) शामिल ([ ऑपरेटर], [लंबाईऑफटाइम], [पॉप], [कारण]) जाओ – dan042988

9

संक्षिप्त उत्तर: नहीं, रिकॉर्ड की कुछ जादू संख्या नहीं है जो एमएसएसएलएल को खराब प्रदर्शन करने का कारण बनती है।

अब, यह संभव प्रश्न अच्छी तरह से स्केल नहीं करेंगे और नतीजतन, डेटासेट जितना बड़ा होगा [घातीय रूप से] इससे भी बदतर होगा।

आपके पास एक बड़ी समस्या यह है कि आप UNIONED कथन के बाद स्टार्टटाइम की भविष्यवाणी कर रहे हैं। इसके बजाय, यूनियन से पहले अपने दोनों चयनों में उस पर भविष्यवाणी करने का प्रयास करें। इससे एक बड़ा अंतर होना चाहिए, खासकर यदि आप स्टार्टटाइम पर दोनों टेबलों को इंडेक्स करते हैं (जेनरेटिंग इंडेक्स उन तालिकाओं पर खोज करता है)।

SELECT * FROM (
SELECT *, ID & YearRec AS ID2 FROM MyFirstTable 
    WHERE STARTTIME >= '8/1/2011 00:00:00' 
    AND STARTTIME <= '8/5/2011 23:59:59' 
UNION ALL SELECT *, ID & YearRec AS ID2 
FROM Table2011 
    WHERE STARTTIME >= '8/1/2011 00:00:00' 
    AND STARTTIME <= '8/5/2011 23:59:59' 
) AS TEMP 

साथ ही आप अपने कोड के कुछ अतिरिक्त रिफैक्टरिंग ऐसा करने में सक्षम हो सकता है।

+0

+1 - 'WHERE' के स्थान के बारे में बहुत अच्छा बिंदु। –

+0

मैं 'यूनियन' के स्थान को ढूंढने के लिए +1 दूंगा। यदि इसे आगे बढ़ाया जा सकता है (2 टेबल अलग-अलग लोगों के साथ अलग हो गए हैं और समूहबद्ध हैं और फिर समेकन का उपयोग करते हैं), तो यह परफॉर्मेंस को और बढ़ा सकता है। आपको अंत में यूनियन की आवश्यकता भी नहीं हो सकती है, केवल 'countFromSubquery1 + countFromSubquery2 AS TotalTime', आदि का उपयोग करके –

+0

क्षमा करें, लेकिन क्वेरी ऑप्टिमाइज़र को इसे संभालना चाहिए - और क्वेरी प्लान को यह दिखाना चाहिए कि क्या यह स्थिति उप भागों के अंदर आईआर के अंदर लागू होती है या नहीं संघ। प्रदर्शन में शून्य अंतर करना चाहिए। – TomTom

संबंधित मुद्दे