2011-12-21 14 views
8

के साथ खराब प्रदर्शन मेरे पास एक वेब सेवा है, इसलिए हैंडलर को हर समय कई बार समझा जाता है।sqlparameter

अंदर मैं एसक्यूएलकनेक्शन और एसक्यूएल कॉमांड बना देता हूं। मुझे लगभग 7 अलग-अलग आदेश निष्पादित करना होगा। विभिन्न आदेशों विभिन्न मापदंडों की आवश्यकता होती है, इसलिए मैं सिर्फ उन्हें एक बार जोड़ें:

command.Parameters.Add(new SqlParameter("@UserID", userID)); 
command.Parameters.Add(new SqlParameter("@AppID", appID)); 
command.Parameters.Add(new SqlParameter("@SID", SIDInt)); 
command.Parameters.Add(new SqlParameter("@Day", timestamp.Date)); 
command.Parameters.Add(new SqlParameter("@TS", timestamp)); 

फिर निष्पादन के दौरान मैं सिर्फ CommandText prorerty बदलने और उसके बाद ExecuteNonQuery फोन(); या ExecuteScalar();

और मुझे प्रदर्शन समस्या का सामना करना पड़ता है। उदाहरण के लिए थोड़ा debuggin और रूपरेखा से पता चलता है, कि कमान

command.CommandText = "SELECT LastShowTS FROM LogForAllTime WHERE UserID = @UserID"; 

avarage में 50ms के बारे में लेता है। अगर मैं इसे बदलता हूं:

command.CommandText = "SELECT LastShowTS FROM LogForAllTime WHERE UserID = '" + userID.Replace("\'", "") + "'"; 

तो यह केवल 1ms अवतार में लेता है!

मुझे समस्या का पता लगाने के लिए सिर्फ एक सुराग नहीं मिल सकता है।

+1

क्या आप बता सकते हैं: सी # में 'userID' का परिभाषित प्रकार क्या है, और डेटाबेस में' UserID' कॉलम का परिभाषित प्रकार क्या है? –

+0

क्या आप वाकई अपनी प्रदर्शन बाधा है? क्या आपने सब कुछ प्रोफाइल किया है? – asawyer

+0

उपयोगकर्ता आईडी एक स्ट्रिंग है, डीबी में यह वर्कर (20) है और एक पीके –

उत्तर

13

ऐसा लगता है कि इसने एक अटूट @UserID मान (शुरुआती लोगों में से एक) के लिए क्वेरी-प्लान कैश किया है, और बाद के प्रश्नों के लिए खराब योजना का पुन: उपयोग कर रहा है। यह दूसरे मामले में कोई मुद्दा नहीं है क्योंकि प्रत्येक की एक अलग योजना है। क्वेरी है, जो इसे कम आँख बंद करके फिर से उपयोग करने की योजना उत्सुक कर देगा करने के लिए

OPTION (OPTIMIZE FOR UNKNOWN) 

: मुझे लगता है तुम सिर्फ जोड़ने की जरूरत है।


वैकल्पिक सिद्धांत:

आप userID के प्रकार (में सी #) और UserID के प्रकार (डेटाबेस में) के बीच एक बेमेल हो सकता है। यह यूनिकोड बनाम एएनएसआई के रूप में सरल हो सकता है, या int बनाम varchar[n], आदि हो सकता है। यदि संदेह में, पैरामीटर को कॉन्फ़िगर करते समय बहुत विशिष्ट सही उप-प्रकार और आकार के साथ जोड़ने के लिए हो सकता है।

स्पष्टीकरण

वास्तव में, यह यहाँ समस्या की तरह दिखता है एक सी # string (यूनिकोड) के बीच का अंतर और डेटाबेस जो varchar(n) है (एएनएसआई) है। इसलिए SqlParameter को स्पष्ट रूप से इस तरह जोड़ा जाना चाहिए (DbType.AnsiString)।

+0

क्या वास्तव में इस तरह के एक सरल 'WHERE' खंड के लिए कोई फर्क पड़ता है? – SLaks

+0

@SLaks अगर डेटा असमान है, हाँ; कल्पना करें: पहली क्वेरी नमूना उपयोगकर्ता के लिए नहीं है (या बहुत कम) डेटा के साथ - क्वेरी ऑप्टिमाइज़र आंकड़ों का उपयोग करता है और पंक्तियों की छोटी संख्या के लिए अनुकूलित क्वेरी प्लान पर निर्णय लेता है। 200k पंक्तियों का सामना करते समय यह काफी हद तक विस्फोट करता है। मैंने बिल्कुल इसी तरह के मामलों को देखा है। इसका पता लगाने का एकमात्र तरीका संकेत के साथ और बिना प्रयास करना है, हालांकि; पी –

+0

अच्छा, यह दिलचस्प विशेषता है कि मैं निश्चित रूप से अधिक विस्तार से जांच करूंगा। अच्छा लिंक यहां है http://blogs.msdn.com/b/sqlprogrammability/archive/2008/11/26/optimize-for-unknown-a-little-known-sql-server-2008-feature.aspx तो मैं कोशिश की है: LogForAllTime कहां UserID = @UserID विकल्प कोई प्रभाव नहीं ... –

0

आप सर्वर पर सात गुना अधिक डेटा भेज रहे हैं, इसलिए यह धीमा हो जाएगा।

इसके अलावा, यदि आपके userID तारों की अलग-अलग लंबाई होती है, तो SQL पैरामीटर में एक स्पष्ट लंबाई निर्धारित करने से यह क्वेरी को बेहतर तरीके से पुन: उपयोग करने की अनुमति देगा।

+0

यह गणना नहीं करता है; यह केवल तब लागू होगा जब पैरामीटर विशाल थे और बैंडविड्थ मुद्दे बाधाएं हैं; मुझे बहुत संदेह है कि यह मामला यहां है। कुछ बुनियादी मानकों को भेजने का समय मामूली है, और ज्यादातर मामलों में विलंबता (बैंडविड्थ की बजाय) से काफी अधिक है। –

+0

@MarcGravell: क्या आप मेरे पहले पैराग्राफ या मेरे दूसरे को संबोधित कर रहे हैं? – SLaks

+0

पहली पंक्ति - मैं 50 एमएम कूद के लिए खाते की अपेक्षा नहीं करता। शायद एक 0.1 एमएमएस विचलन (कोई बड़ा मूल्य मानते हैं)। –

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