2011-10-03 10 views
17

में तेज़ी से मेरे पास एक साधारण सरल क्वेरी है कि मुझे टाइमआउट प्राप्त करना पड़ता है (इसे पूरा करने में तीन मिनट लगते हैं, मैंने इसे जल्दी बंद कर दिया ताकि मैं इस प्रश्न को पोस्ट कर सकूं) जब यह कोड में चल रहा हो , हालांकि जब मैं SQL सर्वर प्रबंधन स्टूडियो में एक ही कंप्यूटर से एक ही क्वेरी चलाता हूं तो प्रश्न बार-बार पूछे जाने वाले प्रश्नों के लिए सर्वर पर कैश नहीं किया गया है और 524 ms पर पहली क्वेरी 2532 ms ले जाएगा।प्रश्न कोड में बेहद धीमी है लेकिन एसएसएमएस

यहाँ मेरी सी # कोड

using (var conn = new SqlConnection("Data Source=backend.example.com;Connect Timeout=5;Initial Catalog=Logs;Persist Security Info=True;User ID=backendAPI;Password=Redacted")) 
       using (var ada = new SqlDataAdapter(String.Format(@" 
SELECT [PK_JOB],[CLIENT_ID],[STATUS],[LOG_NAME],dt 
FROM [ES_HISTORY] 
inner join [es_history_dt] on [PK_JOB] = [es_historyid] 
Where client_id = @clientID and dt > @dt and (job_type > 4 {0}) {1} 
Order by dt desc" 
    , where.ToString(), (cbShowOnlyFailed.Checked ? "and Status = 1" : "")), conn)) 
{ 
    ada.SelectCommand.Parameters.AddWithValue("@clientID", ClientID); 
    ada.SelectCommand.Parameters.AddWithValue("@dt", dtpFilter.Value); 
    //ada.SelectCommand.CommandTimeout = 60; 
    conn.Open(); 
    Logs.Clear(); 
    ada.Fill(Logs); //Time out exception for 30 sec limit. 
} 
यहाँ

है मेरी कोड मैं SSMS में चल रहा है, मैं इसे सही ada.SelectCommand.CommandText

से
declare @clientID varchar(200) 
set @clientID = '138' 
declare @dt datetime 
set @dt = '9/19/2011 12:00:00 AM' 

SELECT [PK_JOB],[CLIENT_ID],[STATUS],[LOG_NAME],dt 
FROM [ES_HISTORY] 
inner join [es_history_dt] on [PK_JOB] = [es_historyid] 
Where client_id = @clientID and dt > @dt and (job_type > 4 or job_type = 0 or job_type = 1 or job_type = 4) 
Order by dt desc 

खींच लिया क्या के लिए प्रमुख विसंगति उत्पन्न कर रहा है समय में अंतर?


टिप्पणी अनुभाग को साफ रखने के लिए, मैं यहां कुछ सामान्य प्रश्नों का उत्तर दूंगा।

उसी कंप्यूटर और लॉगऑन का उपयोग एप्लिकेशन और एसएसएमएस दोनों के लिए किया जाता है।

मेरी उदाहरण क्वेरी में केवल 15 पंक्तियां लौटा दी गई हैं। हालांकि, es_history में 11351699 rows और es_history_dt में 8588493 rows शामिल हैं। दोनों टेबल अच्छी तरह से अनुक्रमित हैं और एसएसएमएस में निष्पादन योजना का कहना है कि वे इंडेक्स का उपयोग कर रहे हैं, वे लुक-अप के लिए खोज करते हैं ताकि वे तेज़ लुकअप हों। कार्यक्रम व्यवहार कर रहा है जैसे कि यह क्वेरी के सी # संस्करण के लिए इंडेक्स का उपयोग नहीं कर रहा है।

+0

क्या आपने एसएसएमएस में कोड के समान उपयोगकर्ता का उपयोग किया था? – bzlm

+1

इस क्वेरी द्वारा कितनी पंक्तियां लौटाई जाती हैं? –

+0

@hugh कृपया मेरा अपडेट देखें .. –

उत्तर

31

एसएसएमएस में आपका कोड वही कोड नहीं है जो आप अपने आवेदन में चलाते हैं। Data Type Precedence के नियमों अपने प्रश्न में Where client_id = @clientID अभिव्यक्ति Sarg नहीं है के कारण

declare @clientID varchar(200) 

:

ada.SelectCommand.Parameters.AddWithValue("@clientID", ClientID); 

जबकि SSMS लिपि में आप VARCHAR के रूप में यह घोषणा करते हैं: अपने आवेदन में यह पंक्ति एक NVARCHAR पैरामीटर जोड़ -able जहां @clientID प्रकार का है NVARCHAR (मैं विश्वास का एक छलांग बना रहा हूं और मानता हूं कि client_id कॉलम VARCHAR प्रकार है)। इस प्रकार एप्लिकेशन एक टेबल स्कैन को मजबूर करता है जहां एसएसएमएस क्वेरी त्वरित कुंजी खोज कर सकती है। पैरामीटर का उपयोग करने के साथ यह एक अच्छी तरह से ज्ञात और समझा मुद्दा है। AddWithValue और पहले कई लेखों में चर्चा की गई है, उदाहरण के लिए। How Data Access Code Affects Database Performance देखें। एक बार समस्या समझा जाता है, समाधान तुच्छ हैं:

फ़िर सेंट समाधान बेहतर है क्योंकि यह SARG-क्षमता समस्या के अतिरिक्त कैश प्रदूषण समस्या हल करता है।

मैं भी आप पढ़ सकते हैं Slow in the Application, Fast in SSMS? Understanding Performance Mysteries

+0

असल में मैंने वर्कर का उपयोग किया क्योंकि फ़ंक्शन के इंटरफ़ेस ने क्लाइंट आईडी को स्ट्रिंग के रूप में पास कर दिया था। मैंने स्कीमा की जांच की और क्लाइंट_आईडी वास्तव में एक int है। प्रश्न को निष्पादित करने से पहले पारित स्ट्रिंग को एक int में परिवर्तित करने के लिए इसे मेरे कोड में बदलना समस्या हल हो गई। धन्यवाद! –

+0

अंतिम लिंक के लिए भी धन्यवाद, यह बहुत उपयोगी है। –

0

अपने ग # कनेक्शन पर प्रोफाइलर चलाने की सिफारिश करेंगे - अन्य गतिविधि है कि आप की जानकारी नहीं है पर जा रहा हो सकता है।

0

जब आप मैन्युअल रूप से अपनी क्वेरी चलाते हैं और फिर जब आप अपना आवेदन चला रहे हों तो प्रोफाइलर से दोनों एसएसएमएस से निष्पादन योजना को कैप्चर करें। तुलना और इसके विपरीत।

0

DBCC FREEPROCCACHE चलाएं, जैसा कि here सुझाया गया है, यह सुनिश्चित करने के लिए कि समस्या एक बाली क्वेरी निष्पादन योजना के कारण नहीं है।

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