2012-08-24 9 views
7

पर्यावरण:ADO.Net SQLCommand.ExecuteReader() को धीमा कर देती या लटका हुआ है

आवेदन (नेट 4 के लिए सी # में लिखा) 10 धागे अप करने के लिए है, इसलिए प्रत्येक धागा अपनी ही AppDomain में चलता है। प्रत्येक थ्रेड एक ADO.Net DataReader का उपयोग करता है जो SQL-Server 2008 पर संग्रहीत प्रक्रिया से परिणाम प्राप्त करता है। इसके अलावा एक थ्रेड एडीओ.Net का उपयोग लिखने के संचालन (थोक सम्मिलन) करने के लिए कर सकता है। सब कुछ स्थानीय मशीन पर चलता है।

समस्या # 1:

कभी कभी (लगभग प्रत्येक 30 रन) एक धागे के निष्पादन के नीचे काफी धीमा कर देती है। ऐसा तब होता है जब DataReader संग्रहीत प्रक्रिया परिणाम प्राप्त करता है - SqlCommand.ExecuteReader()। आम तौर पर पढ़ना ऑपरेशन 10 सेकंड में निष्पादित करता है। जब यह धीमा हो जाता है, तो यह 10-20 मिनट में निष्पादित होता है। एसक्यूएलप्रोफाइलर दिखाता है कि आंकड़े पूछे जा रहे हैं, हालांकि बहुत धीरे-धीरे।

मंदी की Callstack (कृपया ध्यान दें कोई अपवाद नहीं हैं कि):

at SNIReadSync(SNI_Conn* , SNI_Packet** , Int32) 
    at SNINativeMethodWrapper.SNIReadSync(SafeHandle pConn, IntPtr& packet, Int32 timeout) 
    at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj) 
    at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket() 
    at System.Data.SqlClient.TdsParserStateObject.ReadBuffer() 
    at System.Data.SqlClient.TdsParserStateObject.ReadByteArray(Byte[] buff, Int32 offset, Int32 len) 
    at System.Data.SqlClient.TdsParserStateObject.ReadString(Int32 length) 
    at System.Data.SqlClient.TdsParser.ReadSqlStringValue(SqlBuffer value, Byte type, Int32 length, Encoding encoding, Boolean isPlp, TdsParserStateObject stateObj) 
    at System.Data.SqlClient.TdsParser.ReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, Int32 length, TdsParserStateObject stateObj) 
    at System.Data.SqlClient.SqlDataReader.ReadColumnData() 
    at System.Data.SqlClient.SqlDataReader.ReadColumnHeader(Int32 i) 
    at System.Data.SqlClient.SqlDataReader.ReadColumn(Int32 i, Boolean setTimeout) 
    at System.Data.SqlClient.SqlDataReader.GetValueInternal(Int32 i) 
    at System.Data.SqlClient.SqlDataReader.GetValue(Int32 i) 
    at System.Data.SqlClient.SqlDataReader.get_Item(String name) 
    at ****.Core.TableDataImporter.ImportDataFromExcel(Int32 tableId, ExcelEntityLocation location, Boolean& updateResult) in … 

समस्या # 2:

के बजाय एक नीचे एक धागा धीमा लटका कर सकते हैं।

Callstack:

at SNIReadSync(SNI_Conn* , SNI_Packet** , Int32) 
    at SNINativeMethodWrapper.SNIReadSync(SafeHandle pConn, IntPtr& packet, Int32 timeout) 
    at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj) 
    at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket() 
    at System.Data.SqlClient.TdsParserStateObject.ReadBuffer() 
    at System.Data.SqlClient.TdsParserStateObject.ReadByte() 
    at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) 
    at System.Data.SqlClient.SqlDataReader.ConsumeMetaData() 
    at System.Data.SqlClient.SqlDataReader.get_MetaData() 
    at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) 
    at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) 
    at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) 
    at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) 
    at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) 
    at System.Data.SqlClient.SqlCommand.ExecuteReader() 

Callstacks पृष्ठभूमि सूत्र में डिबग उपकरण का उपयोग कर प्राप्त हुए थे। कोई अपवाद नहीं होता है, या तो मंदी या लटकती है।

SNIReadSync एक तंत्र है जो नेटवर्क स्तर पर काम करता है और नेटवर्क पर पैकेट ट्रांसमिट करने के साथ काम करता है। हमने इस समस्या को स्थानीय मशीन पर पुन: उत्पन्न किया है, समीकरण से नेटवर्क समस्याओं को हटा दिया है।

हम इस मंदी/लटका अप के लिए किसी भी इनपुट और समाधान या कामकाज की तलाश में हैं। अभी के लिए हम मंदी का पता लगाने की योजना बना रहे हैं। अग्रिम में धन्यवाद।

मैं विधि के लिए सरलीकृत कोड जोड़कर कर रहा हूँ के रूप में अनुरोध किया:

public void ImportDataFromExcel() 
    {    
     try 
     {     
      var _сonnectionBuilk = ... ; // singleton connection (at the app level) 
      var spName = ... ; // stored procedure name 

     var сonnectionToRead = new SqlConnection(connectionStirng); 
     сonnectionToRead.Open(); 

     var sqlCommand = new SqlCommand(spName); 
     sqlCommand.CommandType = CommandType.StoredProcedure; 
     sqlCommand.Parameters.Add(param1Name, SqlDbType.Int).Value = ...; 
     sqlCommand.Parameters.Add(param2Name, SqlDbType.Int).Value = ...; 
     sqlCommand.Parameters.Add(param2Name, SqlDbType.Int).Value = ...; 

     sqlCommand.Connection = сonnectionToRead;    
     sqlCommand.CommandTimeout = timeout; // 120 sec 

     using (var dataReader = sqlCommand.ExecuteReader()) 
     { 
       dataReader.Read(); 
      ..... 
      int pos1 = dataReader.GetOrdinal(columnName1); 
      int pos2 = dataReader.GetOrdinal(columnName2); 
      int pos3 = dataReader.GetOrdinal(columnName3); 
      int pos4 = dataReader.GetOrdinal(columnName4); 
       .....      

      // reading data from sqldatareader 
      int val1 = dataReader.GetInt32(pos1); 
      int val2 = dataReader.GetInt32(pos2); 
      int val3 = dataReader.GetInt32(pos3); 
      var val4 = dataReader.GetDateTime(pos4); 
      ..... 

      // append read data into bulkTable 
      bulkTable.AddCellValue(val1, val2, val3, val4); // bulkTable wraps DataTable, and appends DataRow inside. 

      if(bulkTable.DataTable.Rows > MaxRowsCount) 
      { 
       using (var bulkCopy = new SqlBulkCopy(_сonnectionBuilk)) 
       { 
        bulkCopy.DestinationTableName = _fullTableName; 
        bulkCopy.WriteToServer(bulkTable.DataTable); 
       } 

       var sqlCommandTransfer = new SqlCommand(spName); 
       sqlCommandTransfer.CommandType = CommandType.StoredProcedure; 
       sqlCommandTransfer.Parameters.Add(param1Name, SqlDbType.Int).Value = ...; 
       sqlCommandTransfer.Connection = _сonnectionBuilk; 
       .... 
       sqlCommandTransfer.ExecuteNonQuery(); // transfering data from temp bulk table into original table 
      } 
     } 
    } 
    finally 
    { 
     bulkTable.Dispose(); 
     сonnectionToRead.Close(); 
    } 
} 
+1

क्या आप कोड दिखा सकते हैं? खासकर जहां आप बना रहे हैं, openeing, कनेक्शन बंद और पाठक निष्पादित कर रहे हैं। –

+2

यह डीबी पक्ष पर एक समस्या की तरह लगता है। क्या एसक्यूएल पर कुछ कार्यकर्ता प्रक्रिया है जो समय-समय पर चलती है? एक सिंच या कुछ क्रिया जो पंक्ति/टेबल लॉक उत्पन्न कर रही है? सारणी कितनी बड़ी है? किस प्रकार की अनुक्रमणिका/बाधाएं आदि – Brian

+0

@TimSchmelter - मैंने लटकने वाले कोड को जोड़ दिया है। – Cortlendt

उत्तर

1

क्योंकि कोड थोड़ी देर के लिए पूरी तरह से काम करता है हम करने के लिए नीचे उसके दायरे को कम कर सकते हैं:/

  • डेटाबेस लॉकिंग से अवरुद्ध अपने प्रक्रियाओं और कुछ अन्य।
  • डेटाबेस केवल अपनी प्रक्रियाओं से लॉक/अवरुद्ध करना।
  • नेटवर्क कनेक्टिविटी।
  • डेटा का राज्य।
  • सर्वर पर डिस्क स्थान या कुछ अन्य प्रतीत होता है असंबंधित समस्या।

मैं कहूंगा कि यह एक डेटाबेस लॉक/ब्लॉक समस्या है। लेकिन आपको निश्चित रूप से निश्चित रूप से यह निर्धारित करने की आवश्यकता है। ऐसा करने के लिए:

  • सुनिश्चित करें कि डिस्क स्थान है जहां डेटाबेस लिख रहे हैं - डेटाबेस लॉग और कोई अन्य लॉगिंग सहित।
  • सुनिश्चित करें कि कोई अन्य प्रक्रिया डेटाबेस का उपयोग नहीं कर रही है।
  • पसंदीदा रूप से स्थानीय डेटाबेस का उपयोग नेटवर्क समस्याओं को खत्म करने के लिए भी करें।
  • आप .Net 4 का उपयोग कर रहे हैं - इसलिए यदि आप कार्य का उपयोग कर रहे हैं तो उन्हें ओवरलोड के साथ सिंक्रनाइज़ करने के लिए बहुत आसान होगा। ऐसा करें और देखें कि समस्या अभी भी है या नहीं।

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

3

हम महीनों के लिए एक समान मुद्दा डिबग करने के लिए आज इसे नीचे ट्रैक किए गए (calliong ToList/toArray/आदि के बिना कोशिश कर दिया गया है, और अंत में ...

हम एक प्रश्न है कि कैश में रखे जा रहा था था। इस पर)। क्वेरी को प्रभावी रूप से एक कनेक्शन से जोड़ा गया था जिसे बाद में साफ किया गया था, और हमें लगता है कि [कोड] ReadSni [/ code] (नीचे पूर्ण स्टैक शामिल) से 100% सीपीयू अवरुद्ध होना प्रतीत होता है।

मुझे संदेह है कि क्वेरी का उपयोग करने के लिए क्वेरी को बदलने से पहले कैशिंग कोड लिखा गया था (और इसके बजाय एक सूची वापस करने के लिए उपयोग किया जाता था, लेकिन फिर भी आईबेम्बरबल के रूप में डाला जाता था) इसलिए इसे तब पेश किया गया जब किसी ने डेटा को "आलसी" पहुंच दिया।

मैं समझा नहीं सकता कि यह उत्पादन में हर कुछ दिनों क्यों हुआ; या तो कैशिंग का बहुत उपयोग नहीं किया जा रहा है, या इस तरह से विफल होने के लिए कनेक्शन को एक निश्चित स्थिति में होना था।

[कोड] ओएस थ्रेड क्रमांक: 0x20b8 (27) बाल सपा आईपी कॉल साइट 16edd0fc 6184267e System.Data.SqlClient.TdsParserStateObject.ReadSni (System.Data.Common.DbAsyncResult, System.Data.SqlClient.TdsParserStateObject) 16edd134 61,842,624 System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket() 16edd144 618446af System.Data.SqlClient.TdsParserStateObject.ReadBuffer() 16edd150 61c583d0 System.Data.SqlClient.TdsParserStateObject.CleanWire() 16edd15c 61d1beb9 System.Data। SqlClient.TdsParser.Deactivate (Boolean) 16edd174 6184995f System.Data.SqlClient.SqlInternalConnectionTds.InternalDeactivate() 16e dd180 61,849,640 System.Data.SqlClient.SqlInternalConnection.Deactivate() 16edd1b0 61,849,587 System.Data.ProviderBase.DbConnectionInternal.DeactivateConnection() 16edd1e4 61,849,405 System.Data.ProviderBase.DbConnectionPool.DeactivateObject (System.Data.ProviderBase.DbConnectionInternal) 16edd224 61849384 System.Data.ProviderBase.DbConnectionPool.PutObject (System.Data.ProviderBase.DbConnectionInternal, System.Object) 16edd26c 6184920c System.Data.ProviderBase.DbConnectionInternal.CloseConnection (System.Data.Common.DbConnection, System.Data.ProviderBase। DbConnectionFactory) 16edd2ac 618490f7 System.Data.SqlClient.SqlInternalConnection.CloseConnection (System.Data.Common.DbConnection, System.Data.ProviderBase.DbConnectionFactory) 16edd2c4 618393bf System.Data.SqlClient.SqlConnection.Close() 16edd304 11238f0a NHibernate.Connection.ConnectionProvider.CloseConnection (System.Data.IDbConnection) 16edd340 11238eae NHibernate.Connection.DriverConnectionProvider.CloseConnection (System.Data.IDbConnection) 16edd34c 11aceb42 NHibernate.AdoNet.ConnectionManager.CloseConnection() 16edd358 11aceb02 NHibernate .AdoNet.ConnectionManager.AggressiveRelease() 16edd364 11acf783 NHibernate.AdoNet.ConnectionManager.AfterTransaction() 16edd370 11acf6d1 NHibernate.Impl.SessionImpl.AfterTransactionCompletion (बूलियन, NHibernate.ITransaction) 16edd3ec 11acf5de NHibernate.AdoNet.ConnectionManager.AfterNonTransactionalQuery (बूलियन) 16edd3fc 11acf539 NHibernate.Impl.AbstractSessionImpl.AfterOperation (बूलियन) 16edd474 130311e4 NHibe rnate.Impl.SessionImpl.List (NHibernate.IQueryExpression, NHibernate.Engine.QueryParameters, System.Collections.IList) 16ede51c 13031071 NHibernate.Impl।AbstractSessionImpl.List (NHibernate.IQueryExpression, NHibernate.Engine.QueryParameters) 16ede538 13030b68 NHibernate.Impl.ExpressionQueryImpl.List() 16ede568 13030a47 NHibernate.Linq.DefaultQueryProvider.ExecuteQuery (NHibernate.Linq.NhLinqExpression, NHibernate.IQuery, NHibernate.Linq .NhLinqExpression) 16ede59c 11d4c163 NHibernate.Linq.DefaultQueryProvider.Execute (System.Linq.Expressions.Expression) 16ede5b0 11d4c108 NHibernate.Linq.DefaultQueryProvider.Execute [System._ कैनन, mscorlib] 16ede5c4 11d4c0a6 Remotion.Linq.QueryableBase 1[[System.__Canon, mscorlib]].GetEnumerator() 16ede5d4 61022108 System.Linq.Enumerable+WhereEnumerableIterator 1 [[प्रणाली। । _Canon, mscorlib]] MoveNext() * चेतावनी: System.Core.ni.dll के लिए checksum सत्यापित करने में असमर्थ * त्रुटि: मॉड्यूल लोड पूरा लेकिन प्रतीकों System.Core.ni.dll

के लिए लोड नहीं हो सका

16ede5e4 610166ea System.Linq.Buffer 1[[System.__Canon, mscorlib]]..ctor(System.Collections.Generic.IEnumerable 1) 16ede620 6122e171 System.Linq.OrderedEnumerable 1+<GetEnumerator>d__0[[System.__Canon, mscorlib]].MoveNext() 16ede63c 79b39758 System.Collections.Generic.List 1 [[सिस्टम .__ कैनन, mscorlib]] .. ctor (System.Collections.Generic.IEnumerable`1) * चेतावनी: असमर्थ mscorlib.ni.dll * त्रुटि के लिए चेकसम को सत्यापित करने के लिए: मॉड्यूल लोड पूरा हो गया लेकिन प्रतीक mscorlib.ni.dll

के लिए लोड नहीं किया जा सका 0

16ede66c 61021acf System.Linq.Enumerable.ToList "> [सिस्टम .__ कैनन, mscorlib] [/ कोड]

+0

क्या आप इस मुद्दे को हल करने में सक्षम थे? यदि हां, तो क्या यह SQL सर्वर पक्ष, ADO.NET पक्ष, या कोड परिवर्तन पर कॉन्फ़िगरेशन समस्या थी? – cortijon

+1

एक कोड परिवर्तन। हमने आइटम को कैश में रखने से पहले ToList() को बुलाया, इसलिए वास्तविक वस्तुओं को अभी तक मूल्यांकन किए गए गणना के बजाय कैश किया गया था। ऐसा नहीं लगता कि हमने इसे तब से देखा है :-) –

0

मैं एक ही समस्या थी और मैं कई परीक्षण मैं अपने विशेष मामले के बारे में बात करने के बाद हल है, लेकिन मुझे लगता है कि यह उपयोगी हो सकता है।

मेरे सिस्टेम में मेरे पास SQLServer 2008 पर एक जटिल ओलाप इंजन है। वर्षों से, ऑपरेशन वॉल्यूम और मात्रा में बढ़े और यादृच्छिक रूप से मुझे पोस्ट में उल्लिखित त्रुटि मिली ... ऑपरेशन बढ़ाने से त्रुटि दूर हो गई। मैंने ओएलएपी के सभी परिचालनों के कोड की दोबारा जांच की और सभी लेनदेन, कनेक्शन, और पाठक वस्तुओं को पूरी तरह से संभाला गया।

महत्वपूर्ण बात यह है कि उत्पन्न त्रुटियों (लेकिन हमेशा नहीं) जब मैं जबकि के वर्गों SQLServer के लिए क्वेरी करने के लिए लूप था, querys के बार-बार बमबारी त्रुटियों डीबी में

हो ristrutturato le molte piccole querys में ऊना क्वेरी più उत्पन्न दादी (टर्मिनी डी परिणाम में) एड हो ऑपरेटो डेले ऑपरेटिंग लाइनक्यू, LINI, आईएल risultato è stato soprendente। Perdormance di 10 volte migliorate e 0 errori।

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

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