2014-12-09 9 views
8

हम पहले से ही चल रहे एक प्रणाली है कि सभी कनेक्शन-तार (डीबी 2, ओरेकल, MSServer) संभालती है।लाख आवेषण: SqlBulkCopy टाइमआउट

वर्तमान में, हम कुछ प्रविष्टियों के लिए ExecuteNonQuery() का उपयोग कर रहे हैं।

हम के बजाय SqlBulkCopy() का उपयोग करके प्रदर्शन में सुधार करना चाहते हैं। हमारे पास कुछ क्लाइंट हैं जिनमें 50 मिलियन से अधिक रिकॉर्ड हैं।

हम एसएसआईएस का उपयोग नहीं करना चाहते हैं, क्योंकि हमारी प्रणाली एकाधिक डेटाबेस का समर्थन करती है।

मैंने SqlBulkCopy() के प्रदर्शन का परीक्षण करने के लिए एक नमूना प्रोजेक्ट बनाया। मैं एक साधारण पढ़ा बनाया है और के लिए समारोह डालने MSServer

यहाँ छोटे समारोह है:

public void insertIntoSQLServer() 
{ 
    using (SqlConnection SourceConnection = new SqlConnection(_sourceConnectionString)) 
    { 
     //Open the connection to get the data from the source table 
     SourceConnection.Open(); 
     using (SqlCommand command = new SqlCommand("select * from " + _sourceSchemaName + "." + _sourceTableName + ";", SourceConnection)) 
     { 
      //Read from the source table 
      command.CommandTimeout = 2400; 
      SqlDataReader reader = command.ExecuteReader(); 

      using (SqlConnection DestinationConnection = new SqlConnection(_destinationConnectionString)) 
      { 
       DestinationConnection.Open(); 
       //Clean the destination table 
       new SqlCommand("delete from " + _destinationSchemaName + "." + _destinationTableName + ";", DestinationConnection).ExecuteNonQuery(); 

       using (SqlBulkCopy bc = new SqlBulkCopy(DestinationConnection)) 
       { 
        bc.DestinationTableName = string.Format("[{0}].[{1}]", _destinationSchemaName, _destinationTableName); 
        bc.NotifyAfter = 10000; 
        //bc.SqlRowsCopied += bc_SqlRowsCopied; 
        bc.WriteToServer(reader); 
       } 
      } 
     } 
    } 
} 

जब मैं कम है कि मेरे dummyTable में 200 000 थोक प्रतिलिपि ठीक काम कर रहा है। लेकिन, जब 200,000 से अधिक रिकॉर्ड हैं, तो मेरे पास निम्न त्रुटियां हैं:

  • लंबित ऑपरेशन वाले ऑब्जेक्ट पर थोक प्रतिलिपि लगाने का प्रयास करें।

या

  • इंतजार प्रचालन का समय समाप्त (IDataReader के लिए)

मैं पाठक के लिए CommandTimeout वृद्धि हुई है। ऐसा लगता है कि उसने IDataReader से संबंधित टाइमआउट समस्या हल कर दी है।

क्या मैं कोड में कुछ गलत कर रहा हूं?

+1

कभी भी लक्ष्य तालिका में SqlBulkCopy कभी नहीं। उस चीज ने लॉकिंग कोड को गंभीरता से तोड़ दिया है। विशेष रूप से बहु थ्रेडिंग का उपयोग करते समय। एक अस्थायी तालिका बनाएं, उसमें डालें, फिर लक्ष्य तालिका में कॉपी करें। – TomTom

+0

मैं बहु थ्रेडिंग का उपयोग नहीं कर रहा हूं। मैं हमेशा एक खाली टेबल में डाल रहा हूँ। – billybob

+2

क्यों sqlbulkcopy बिल्कुल? गंभीरता से। उसी डेटाबेस पर टेबल्स - बस इसे अपलोड करने के लिए इसे अपने प्रोग्राम में खींचने के बजाय डेटा कॉपी करने के लिए सर्वर को कॉपी करें। एक कथन के साथ लक्ष्य तालिका में सही का चयन करें। – TomTom

उत्तर

9

आप WriteToServer करने के लिए कॉल करने से पहले निम्न जोड़ने ...

bc.BatchSize = 10000; 
bc.BulkCopyTimeout = 0; 

मैं नहीं जानता कि क्या डिफ़ॉल्ट बैच आकार या समय समाप्ति है की कोशिश कर सकते हैं, लेकिन मैं इससे आपकी समस्या का हो सकता है संदेह है। आशा है कि

मदद करता है, इसके अलावा, आप इष्टतम प्रदर्शन के लिए विभिन्न बैच आकारों के साथ खेलने का प्रयास कर सकते हैं।

0

आप यह

bc.BatchSize = 100,000; // एक समय में आप कितनी पंक्तियां डालना चाहते हैं।

bc.BulkCopyTimeout = 60; // सेकेंड में समय, यदि आप अनंत प्रतीक्षा समय चाहते हैं तो 0

आशा है कि यह आपको और अन्य डेवलपर्स को भी मदद करेगा।