2009-04-29 15 views
18

मेरे पास एक संग्रहित प्रक्रिया है जो System.Data.SqlClient.SqlCommand (2 मिनट के बाद के समय) के साथ चलाने के दौरान एसक्यूएल सर्वर प्रबंधन स्टूडियो (2 सेकंड) से बहुत तेज निष्पादित करती है।SqlCommand के साथ उपयोग किए जाने पर कुछ एसक्यूएल क्वेरी कितनी धीमी है?

इसका कारण क्या हो सकता है?


विवरण: Sql सर्वर प्रबंधन स्टूडियो में इस (उत्पादन डेटाबेस पर) 2 सेकंड में चलाता है:

EXEC sp_Stat 
    @DepartmentID = NULL 

में नेट/सी # निम्नलिखित समय बाहर 2 मिनट के बाद (उत्पादन डेटाबेस पर) :

string selectCommand = @" 
EXEC sp_Stat 
    @DepartmentID = NULL"; 
string connectionString = "server=***;database=***;user id=***;pwd=***"; 
using (SqlConnection connection = new SqlConnection(connectionString)) 
{ 
    using (SqlCommand command = new SqlCommand(selectCommand, connection)) 
    { 
     connection.Open(); 
     using (SqlDataReader reader = command.ExecuteReader()) 
     { 
      while (reader.Read()) 
      { 
      } 
     } 
    } 
} 

मैं भी selectCommand = "sp_Stat", CommandType = StoredProcedure, और एक SqlParameter साथ करने की कोशिश की है, लेकिन यह एक ही परिणाम है।

और EXEC के बिना यह भी वही परिणाम है।

लगभग डेटा-खाली विकास डेटाबेस पर दोनों मामले 1 सेकंड से भी कम समय में समाप्त होते हैं। तो यह वहाँ डेटाबेस में डेटा का एक बहुत है कि से संबंधित है, लेकिन यह केवल नेट से हो रहा है ...


क्या मार्क Gravell अलग SET मूल्यों के बारे में लिखा प्रस्तुत मामले में फर्क नहीं पड़ता।

एसक्यूएल सर्वर प्रोफाइलर से पता चला है Sql सर्वर प्रबंधन स्टूडियो चलाता है जो निम्न SET की जो .NET Sql क्लाइंट डेटा प्रदाता नहीं करता है:


SET ROWCOUNT 0 
SET TEXTSIZE 2147483647 
SET NOCOUNT OFF 
SET CONCAT_NULL_YIELDS_NULL ON 
SET ARITHABORT ON 
SET LOCK_TIMEOUT -1 
SET QUERY_GOVERNOR_COST_LIMIT 0 
SET DEADLOCK_PRIORITY NORMAL 
SET TRANSACTION ISOLATION LEVEL READ COMMITTED 
SET ANSI_NULLS ON 
SET ANSI_NULL_DFLT_ON ON 
SET ANSI_PADDING ON 
SET ANSI_WARNINGS ON 
SET CURSOR_CLOSE_ON_COMMIT OFF 
SET IMPLICIT_TRANSACTIONS OFF 
SET QUOTED_IDENTIFIER ON 
SET NOEXEC, PARSEONLY, FMTONLY OFF 

जब मैं इन शामिल एक ही क्वेरी उतना ही समय ले लिया एसएसएमएस और .NET में। और जिम्मेदार SET

SET ARITHABORT ON 

मैं क्या सीखा है ...? हो सकता है कि अनुमान लगा के बजाय एक प्रोफाइलर उपयोग करने के लिए ...

(पहली बार में समाधान सूँघने पैरामीटर के लिए संबंधित होने के लिए लग रहा था। लेकिन मैं कुछ चीजें मिश्रित था ...)

+0

विचार करने के लिए एक और बात: यदि आपके पास 'एरिथबॉर्ट ऑफ़' के साथ प्रदर्शन जुर्माना है तो आप स्ट्रिंग और न्यूमेरिक फ़ील्ड द्वारा दो टेबलों में शामिल हो सकते हैं। मेरे मामले में, एक सरल 'ISNUMERIC (string_field) = 1' जोड़ना _before_ समस्या को हल करने में शामिल हों :) – Loris

+0

मैंने कभी यह नहीं माना होगा - बहुत उपयोगी प्रश्न/उत्तर! :) हमारे पास सिर्फ एक कच्ची एसक्यूएल क्वेरी है जिसे डैपर के माध्यम से निष्पादित किया जा रहा है और वही एसईटी अपराधी था। – Jedidja

+0

एप्लिकेशन परत में ARITHABORT को सेट करने के बारे में जागरूक रहें .. "अपनी प्रक्रिया पर सेट एथिबैबर्ट जोड़ना कोई समाधान नहीं है। जब आप इसे आजमाते हैं तो यह काम करेगा। लेकिन ऐसा इसलिए है क्योंकि आपने प्रक्रिया को फिर से बनाया है जिसने एक नया संकलन मजबूर किया है" यहां पूरा लेख: http://www.sommarskog.se/query-plan-mysteries.html –

उत्तर

10

एक और बात है कि महत्वपूर्ण हो सकता है 012,313,450 हैजो सक्षम हैं। इनमें से कुछ विकल्प प्रोफाइल बदलने के लिए पर्याप्त रूप से क्वेरी योजना को बदलते हैं। अगर आप (गणना के लिए) एक गणना + जारी (और संभवतः अनुक्रमित) कॉलम देख रहे हैं तो कुछ का बड़ा प्रभाव हो सकता है: यदि SET विकल्प संगत नहीं हैं, तो इसे उपयोग करने के बजाय मूल्यों की पुन: गणना करने के लिए मजबूर किया जा सकता है अनुक्रमित मान - जो एक इंडेक्स को तालिका स्कैन + गणना में बदल सकता है।

यह देखने के लिए प्रोफाइलर का उपयोग करने का प्रयास करें कि SET विकल्प "play में" हैं, और देखें कि उन विकल्पों का उपयोग करने से चीज़ें बदलती हैं।

कनेक्शन स्ट्रिंग का एक और प्रभाव है; उदाहरण के लिए, यदि आप मार्स सक्षम करते हैं जो सूक्ष्म तरीकों से व्यवहार को बदल सकते हैं।

अंत में, लेन-देन (अंतर्निहित (TransactionScope) या स्पष्ट) अलगाव के स्तर पर निर्भर करता है, एक विशाल प्रभाव हो सकता है।

+0

धन्यवाद। मैं एसईटी विकल्पों की जांच कैसे करूंगा।मुझे लगता है कि यह अंतर से संबंधित हो सकता है, क्योंकि अन्यथा प्रश्न समान हैं ... –

+0

हाय मार्क, मुझे इस मुद्दे को एक डीबी पर चल रहा है जो चल रहा है, और एकमात्र समाधान सेट एंटिबॉर्ट ऑन/संग्रहीत प्रो पर बंद करें। Unfortuntley यह हो रहा है और मुझे ARITHABORT विकल्प को इसके विपरीत के विपरीत बदलना है। क्या आप एसईएमएस का उपयोग करने के समान एसईटी विकल्पों का उपयोग करने के लिए मेरे .NET ऐप को बताने के किसी भी तरीके से जानते हैं? –

+0

क्या ड्रैपर, मार्क के साथ ARITHABORT को कॉन्फ़िगर करना संभव है? क्या यह ऐसा कुछ है जो कमांड स्तर की बजाय कनेक्शन स्तर पर सेट है? क्या यह एक एसक्यूएल कमांड है जब भी मैं कनेक्शन स्थापित करता हूं? – crush

0

हम एक समान मुद्दा है, जहां था एक क्वेरी एसएसएमएस में 2 सेकंड में पूर्ण हो जाएगी और .NET क्लाइंट से कॉल किए जाने पर 90 सेकंड से अधिक समय ले लें (हमने कई वीबी/सी # ऐप्स/साइट्स का परीक्षण करने के लिए लिखा है।)

हमें संदेह है कि क्वेरी योजना अलग होगी , और स्पष्ट लूपिंग ("आंतरिक लूप जॉइन" और "इंडेक्स के साथ") संकेतों के साथ क्वेरी को दोबारा लिखें। इसने समस्या हल की।

+0

आशा है कि आपने पहले अपने आंकड़े और अनुक्रमणिका की जांच की है! ;) –

+0

हाँ, हमारे पास आंकड़े और अनुक्रमणिका के लिए साप्ताहिक रखरखाव योजना है (प्रत्येक रविवार को चलता है।) हमने किसी भी कैश किए गए क्वेरी प्लान को हटाने के लिए संग्रहीत प्रक्रिया को फिर से बनाया है। – Andomar

5

यह लगभग निश्चित रूप से 'गलत' कैश की गई क्वेरी योजना के कारण है। यह कुछ बार कुछ समय पर आया है।

क्या आपके पास अद्यतित आंकड़े हैं? एक नियमित अनुसूचित सूचकांक रखरखाव योजना?

आप अपने संग्रहीत प्रक्रिया परिभाषा को यह जोड़कर अगर यह कैश की गई क्वेरी योजना के कारण निश्चित रूप से है परीक्षण कर सकते हैं:

CREATE PROCEDURE usp_MyProcedure WITH RECOMPILE... 

यह होगा फिर से सूचकांक एक पूरे डेटाबेस (सावधानी यदि डेटाबेस बहुत बड़ी है!):

exec sp_msforeachtable "dbcc dbreindex('?')" 

अतः पोस्ट:

Big difference in execution time of stored proc between Managment Studio and TableAdapter.

Parameter Sniffing (or Spoofing) in SQL Server

optimize for unknown for SQL Server 2005?

Different Execution Plan for the same Stored Procedure

+0

मैंने एक ही के बाद ठीक उसी प्रश्न (EXEC sp_Stat @DepartmentID = NULL) चलाया। सबसे पहले वह जो एसएसएमएस के साथ 2 सेकंड लेता था। फिर (कुछ सेकंड बाद) जो .NET से बाहर आया था। क्या आपको लगता है कि यह अभी भी गलत तरीके से कैश की गई क्वेरी योजना से संबंधित हो सकता है? –

+0

या तो आंकड़े पुराने हैं या इंडेक्स को पुनर्निर्मित करने की आवश्यकता है (जो संबंधित कॉलम पर आंकड़े अपडेट करते हैं) –

+0

मैं सटीक समान पैरामीटर का उपयोग करता हूं। और RECOMPILE विकल्प के साथ परिणाम नहीं बदलता है ... –

0

एक समान समस्या थी और यह कनेक्शन स्ट्रिंग (जिसे न्यूनतम प्रभाव माना जाता है) में एकाधिकActiveResultSets = सच हो रहा है, रिमोट कनेक्शन पर 1.5 मिलीलीटर रिकॉर्ड खींचने से लगभग 2 मिनट के बजाय 25 मिनट लगते हैं।

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