5

मुझे SQL डेटाबेस क्वेरी के साथ कोई समस्या है जो अचानक (लेकिन नियमित रूप से हर तीन सप्ताह के बारे में) धीमा हो जाता है।SQL सर्वर क्वेरी अचानक धीमी

  • विंडोज सर्वर 2008 (नहीं R2) 64 बिट, 8 जीबी रैम
  • SQL सर्वर एक्सप्रेस 2008 R2
  • डेटाबेस 6 GB की आकार की है (mdf फ़ाइल:

    सेटअप निम्नलिखित है आकार)

  • तालिका (Orders) क्वेरी मुख्य रूप से चयन किया गया है चारों ओर 24000 रिकॉर्ड है, पांच अन्य में शामिल हो गए टेबल छोटे (100 रिकॉर्ड या उससे कम)
  • तालिका Orders एक 012,366 है कर रहे हैंकॉलम Report जिसमें 200 से 300 केबी के औसत आकार के साथ बाइनरी डेटा (पीडीएफ दस्तावेज़) शामिल है (लेकिन कभी-कभी 2 एमबी तक हो सकता है)। उन 24000 ऑर्डरों में से 9 0% से अधिक इस कॉलम को भर चुके हैं, अन्य लोगों के लिए यह NULL है, यानी 6 जीबी डेटाबेस आकार का 90% से अधिक बाइनरी डेटा हैं।

    SELECT TOP (30) [Project2].[OrderID] AS [OrderID] 
           -- around 20 columns more 
    FROM (SELECT [Project2].[OrderID] AS [OrderID], 
           -- around 20 columns more 
           row_number() OVER (ORDER BY [Project2].[OrderID] ASC) AS [row_number] 
         FROM (SELECT [Filter1].[OrderID] AS [OrderID] 
           -- around 20 columns more 
           FROM (SELECT [Extent1].[OrderID] AS [OrderID] 
            -- around 20 columns more 
            FROM [dbo].[Orders] AS [Extent1] 
            INNER JOIN -- small table 
            LEFT OUTER JOIN -- small table 
            LEFT OUTER JOIN -- small table 
            LEFT OUTER JOIN -- small table 
            LEFT OUTER JOIN -- small table 
            WHERE ([Extent1].[Status] IS NOT NULL) 
             AND (4 = CAST([Extent1].[Status] AS int)) 
             AND ([Extent1].[SomeDateTime] IS NULL) 
             AND ([Extent1].[Report] IS NULL) 
            ) AS [Filter1] 
           OUTER APPLY (SELECT TOP (1) [Project1].[C1] AS [C1] 
              FROM (SELECT CAST([Extent7].[CreationDateTime] AS datetime2) AS [C1], 
                   [Extent7].[CreationDateTime] AS [CreationDateTime] 
                FROM [dbo].[OtherTable] AS [Extent7] 
                WHERE [Filter1].[OrderID] = [Extent7].[OrderID] 
               ) AS [Project1] 
              ORDER BY [Project1].[CreationDateTime] DESC 
          ) AS [Limit1] 
         ) AS [Project2] 
    ) AS [Project2] 
    WHERE [Project2].[row_number] > 0 
    ORDER BY [Project2].[OrderID] ASC 
    

    यह इकाई की रूपरेखा से एक LINQ करने वाली संस्थाओं क्वेरी से उत्पन्न होता है:

प्रश्न में क्वेरी निम्नलिखित संरचना है। क्वेरी में कुछ बदलाव के जो पहले WHERE खंड में केवल अलग हैं में होता है:

  • पाँच वेरिएंट

    WHERE ([Extent1].[Status] IS NOT NULL) 
        AND (X = CAST([Extent1].[Status] AS int)) 
    

    एक्स 0 और 4 के बीच हो सकता है। ये प्रश्न कभी समस्या नहीं हैं।

  • और दो वेरिएंट (*)

    WHERE ([Extent1].[Status] IS NOT NULL) 
        AND (4 = CAST([Extent1].[Status] AS int)) 
        AND ([Extent1].[SomeDateTime] IS NULL) 
        AND ([Extent1].[Report] IS NULL) 
    

    या ... IS NOT NULL... अंतिम पंक्ति में। मुझे केवल उन दो प्रश्नों के साथ वर्णित समस्या है।

घटना "" है:

  • दो प्रश्नों (*) प्रति सप्ताह 5 दिनों 100 से 200 दिन में कई बार, चलाए जा रहे हैं। वे लगभग तीन सप्ताह के लिए एक सेकंड से भी कम समय के साथ प्रदर्शन करते हैं।
  • तीन सप्ताह के बाद दोनों प्रश्नों को अचानक 60 सेकंड से अधिक की आवश्यकता होती है। (इस बार वास्तव में बढ़ते डेटाबेस आकार के साथ बढ़ता है।) उपयोगकर्ताओं को एक टाइमआउट के कारण एक त्रुटि (वेब ​​पेज पर; यह एक वेब ऐप है) मिलता है। (इकाई फ्रेमवर्क डिफ़ॉल्ट रूप से परिणाम के लिए 30 सेकंड से अधिक समय तक प्रतीक्षा नहीं कर रहा है।)
  • यदि मैं क्वेरी को एसएसएमएस में पेस्ट करता हूं और क्वेरी को चलाने देता हूं (60 सेकंड प्रतीक्षा कर रहा हूं) परिणाम सफलतापूर्वक वापस आ गया है और अगला क्वेरी एक सेकंड से भी कम समय में फिर से चलती है।
  • लगभग तीन सप्ताह में एक ही फिर से होता है के बाद (लेकिन समय क्वेरी रन 65 या 70 सेकंड तो हो जाएगा)

एक अतिरिक्त अवलोकन:

  • मैं एसक्यूएल सर्वर सेवा प्रक्रिया को पुनः प्रारंभ करते हैं कभी-कभी जब क्वेरी सामान्य होती है, प्रक्रिया का स्मृति उपयोग धीरे-धीरे बढ़ता है। यह लगभग एक हफ्ते के भीतर चरणबद्ध कदम से लगभग 1,5 जीबी (टास्क मैनेजर में निजी कामकाजी सेट) की सीमा तक पहुंचता है।
  • यदि क्वेरी अचानक धीमी हो जाती है और फिर क्वेरी को ट्रिगर करता है तो मैं SQL सर्वर सेवा प्रक्रिया को पुनरारंभ करता हूं, मैं कार्य प्रबंधक में देख सकता हूं कि सेवा कुछ सेकंड के भीतर लगभग 1 जीबी लोड करती है।

किसी तरह मुझे लगता है पूरी समस्या एक्सप्रेस संस्करण की स्मृति सीमा (1 जीबी) और varbinary(MAX) स्तंभ के साथ क्या करना है, हालांकि मैं अभी WHERE खंड यदि स्तंभ मान NULL है या नहीं की जाँच करता है कि में इसका इस्तेमाल किया है NULLReport कॉलम स्वयं चयनित कॉलम में से एक नहीं है।

जब से मैं सीमाओं के खिलाफ चल रहा हूँ (10 जीबी mdf फ़ाइल आकार) एक्सप्रेस संस्करण के अगले साल नवीनतम मैं वैसे भी परिवर्तन पर विचार कर रहा हूँ:

  • या तो एक और मेज पर द्विआधारी स्तंभ के लिए कदम और बाह्य सामग्री को संग्रहीत FILESTREAM के माध्यम से,, एक्सप्रेस संस्करण
  • उपयोग "बड़ी" SQL सर्वर एक्सप्रेस सीमाओं के बिना संस्करणों में से एक का उपयोग कर रखने के Orders तालिका में द्विआधारी स्तंभ रखने
  • दोनों
करें 210

प्रश्न: प्रश्न अचानक धीमा होने का कारण क्या हो सकता है? क्या मैं बदलावों में से कोई एक समस्या हल कर सकता हूं या क्या अन्य समाधान हैं?

संपादित

टिप्पणियां मैं क्वेरी फिर से चलाने से पहले SSMS में SET STATISTICS TIME ON निर्धारित किया है नीचे में bhamby के टिप के बाद। जब क्वेरी दोबारा धीमी हो जाती है तो मुझे SQL Server parse and compile time के लिए उच्च मान मिलता है, अर्थात्: CPU time = 27,3 sec और Elapsed time = 81,9 sec। क्वेरी के लिए निष्पादन समय केवल CPU समय = 0,06 सेकंड और समाप्त समय = 2,8 सेकेंड है। क्वेरी को दूसरी बार चलाने के बाद CPU सर्वर 0,06 सेकंड और SQL सर्वर पार्स और संकलन समय के लिए समाप्त समय = 0,08 देता है।

+0

क्या आप इस प्रक्रिया को (3) अलग कर सकते हैं जो इस 3 सप्ताह के अंतराल के साथ मेल खाता है? लगता है कि प्रतिस्पर्धा के अलावा कुछ भी उस तरह के असंगत प्रदर्शन का कारण बन जाएगा। –

+0

@GoatCO: मैंने कई बार जांच की थी, लेकिन अन्य प्रक्रियाओं के साथ कोई प्रतिस्पर्धा नहीं है। आवृत्ति * बिल्कुल * 3 सप्ताह नहीं है, यह कुछ दिन या उससे कम हो सकती है और यह सुबह या दोपहर में हो सकती है। जब ऐसा होता है तो सर्वर पर न तो उच्च CPU और न ही स्मृति लोड होता है। और समस्या कभी भी गायब नहीं होती है (जो मुझे उम्मीद है कि अगर कुछ अन्य प्रतिस्पर्धी प्रक्रिया समाप्त होती है)। एसएसएमएस में एक बार मैंने पाया एकमात्र तरीका क्वेरी चला रहा है। – Slauma

+0

आह यह दिलचस्प है। यदि आप समय-समय पर एसएसएमएस में इसे चलाते हैं तो क्या आप मंदी को पूरी तरह से रोक सकते हैं, या फिर भी ऐसा होता है? –

उत्तर

2

यह सिर्फ बेकार लगता है

SELECT TOP (1) [Project1].[C1] AS [C1] 
FROM (SELECT CAST([Extent7].[CreationDateTime] AS datetime2) AS [C1], 
        [Extent7].[CreationDateTime] AS [CreationDateTime] 
     FROM [dbo].[OtherTable] AS [Extent7] 
     WHERE [Filter1].[OrderID] = [Extent7].[OrderID] 
    ) AS [Project1] 
ORDER BY [Project1].[CreationDateTime] DESC 

SELECT max(CAST([Extent7].[CreationDateTime] AS datetime2)) AS [C1] 
    FROM [dbo].[OtherTable] AS [Extent7] 
WHERE [Filter1].[OrderID] = [Extent7].[OrderID] 

दिनांक के रूप में आप क्यों भंडारण नहीं कर रहे हैं दिनांकों है?

मुझे लगता है कि बाहरी पसंद नहीं लागू
मैं एक #temp है कि एक बार चलाया जाता है बना सकते हैं और इसे करने के लिए शामिल होने के
सुनिश्चित करें और घोषित [OrderID] के रूप में पी

SELECT [Extent7].[OrderID], max(CAST([Extent7].[CreationDateTime] AS datetime2)) AS [C1] 
FROM [dbo].[OtherTable] AS [Extent7] 
GROUP BY [Extent7].[OrderID] 

आप पाश हो सकता था होगा पर

अगला जा रहा शामिल होने मैं # temp2 में रखते हैं ताकि आप यकीन है कि यह केवल एक बार चलाया जाता है
फिर एक पी के रूप में OrderID घोषित करने के लिए सुनिश्चित हो रहे हैं

SELECT [Extent1].[OrderID] AS [OrderID] 
        -- around 20 columns more 
        FROM [dbo].[Orders] AS [Extent1] 
        INNER JOIN -- small table 
        LEFT OUTER JOIN -- small table 
        LEFT OUTER JOIN -- small table 
        LEFT OUTER JOIN -- small table 
        LEFT OUTER JOIN -- small table 
        WHERE ([Extent1].[Status] IS NOT NULL) 
         AND (4 = CAST([Extent1].[Status] AS int)) 
         AND ([Extent1].[SomeDateTime] IS NULL) 
         AND ([Extent1].[Report] IS NULL) 

यदि ऑर्डर केवल 24,000 पंक्तियां है तो कुछ सेकंड से अधिक प्रश्न पूछने के लिए कुछ बेवकूफ चल रहा है।

+0

+1: 'अधिकतम' का उपयोग करना एक अच्छा बिंदु है! मैंने इसी LINQ क्वेरी को दूसरी क्वेरी से लिया है जहां मैं वास्तव में केवल 'CreationDateTime' की तुलना में अधिक कॉलम चुनता हूं। लेकिन इस संस्करण में 'अधिकतम' वास्तव में समझदार लगता है। मैं कोशिश करूँगा! बीटीडब्लू: 'क्रिएशनडेट टाइम' को 'डेटाटाइम 2 (0)' के रूप में संग्रहीत किया जाता है। (अनावश्यक) 'CAST' किसी भी कारण से इकाई फ्रेमवर्क द्वारा उत्पन्न होता है। 'ऑर्डर आईडी' पीके बीटीडब्ल्यू है। – Slauma

+0

फिर कास्ट लें क्योंकि इसमें समय लगता है। – Paparazzi

0

यदि यह एक क्वेरी है जो अक्सर चलती है, तो मैं इसे एक संग्रहीत प्रक्रिया में बदलने और प्रक्रिया के परिणामों का उपयोग करने का सुझाव दूंगा।

इकाई फ्रेमवर्क में आप प्रक्रिया को Function Import के रूप में आयात करने में सक्षम होना चाहिए।

फिर आप query hints देकर याका मुकाबला करके संग्रहीत प्रक्रिया की निष्पादन योजना पर नियंत्रण ले सकते हैं।

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

इसके अलावा, आपने उल्लेख किया है कि आप 64 बिट एसक्यूएल का उपयोग कर रहे हैं। मेरा अनुभव यह रहा है कि 64 बिट एसक्यूएल उप-प्रश्नों के साथ बहुत कुशलतापूर्वक प्रदर्शन नहीं करता है। मेरी सलाह होगी कि वे कोशिश करें और उनसे बचें।

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