2011-02-01 25 views
5

में 200 मिलियन पंक्तियों सम्मिलित करना मैं जो मैं गति के लिए अनुकूलित करना चाहते हैं निम्नलिखित (सरलीकृत) कोड:सी # अनुकूलन: डेटाबेस

long inputLen = 50000000; // 50 million 
DataTable dataTable = new DataTable(); 
DataRow dataRow; 
object[] objectRow; 
while (inputLen--) 
{ 
    objectRow[0] = ... 
    objectRow[1] = ... 
    objectRow[2] = ... 

    // Generate output for this input 
    output = ... 

    for (int i = 0; i < outputLen; i++) // outputLen can range from 1 to 20,000 
    { 
     objectRow[3] = output[i]; 
     dataRow = dataTable.NewRow(); 
     dataRow.ItemArray = objectRow; 
     dataTable.Rows.Add(dataRow); 
    } 
} 

// Bulk copy 
SqlBulkCopy bulkTask = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, null); 
bulkTask.DestinationTableName = "newTable"; 
bulkTask.BatchSize = dataTable.Rows.Count; 
bulkTask.WriteToServer(dataTable); 
bulkTask.Close(); 

मैं पहले से ही सब कुछ तेज़ करने की कोशिश में SqlBulkCopy उपयोग कर रहा हूँ , लेकिन ऐसा लगता है कि डेटाटेबल को मान असाइन करना धीमा साबित होता है।

मुझे नहीं पता कि डेटाटेबल्स कैसे काम करते हैं, इसलिए मुझे आश्चर्य है कि क्या मैं पहले पुन: प्रयोज्य सरणी बनाकर अनावश्यक ओवरहेड बना रहा हूं, फिर इसे डेटारो में असाइन कर रहा हूं, फिर डेटाटेव को डेटाटेबल जोड़ रहा हूं? या डेटाटेबल का उपयोग पहली जगह इष्टतम नहीं है? इनपुट डेटाबेस से आता है।

मुझे बस, बस गति के बारे में ज्यादा परवाह नहीं है। क्या कोई इस पर कुछ सलाह दे सकता है?

+0

उदाहरण कार्यान्वयन के लिए, 'SimpleDataReader' [यहां] देखें (https://groups.google.com/group/microsoft.public.dotnet.languages.csharp/msg/b1d70b504cdee2ad?hl=hi) –

उत्तर

13

इतनी बड़ी मेज के लिए, आप के बजाय

public void WriteToServer(IDataReader reader) 

विधि का उपयोग करना चाहिए।

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

+1

याद रखें कि आप मुझे इसे हराते हैं :) –

+0

क्या इसका मतलब है कि SQLBulkCopy अभी भी डेटाबेस के लिए कुशलतापूर्वक लिख सकता है ** ** पंक्तियां बनाई जा रही हैं ? इनपुट एक ही डेटाबेस से आ रहा है, लेकिन प्रत्येक पंक्ति के लिए मैं संभावित रूप से 20000 नए बना रहा हूं। –

+0

@ बॉक्स 9 हां, ठीक है कि –

0

आपको स्मृति में संपूर्ण डेटाटेबल का निर्माण नहीं करना चाहिए। WrtieToServer के overload का उपयोग करें, जो DataRow की सरणी लेता है। बस अपने डेटा में भाग विभाजित करें।

+0

Isn' टी विधि अभी भी स्मृति में इसे बना रहा है? और इसके अलावा, अगर मैं स्मृति से बाहर नहीं चल रहा हूं, तो इसे स्मृति में सबसे तेज़ नहीं बना रहा है? –

+0

यदि आप 200 मीटर की बजाय एक बार में केवल 1k पंक्तियां बनाते हैं तो स्मृति प्रबंधक के लिए इस तरह के डेटा को पकड़ना बहुत आसान होगा। इसके अलावा, आप लगभग 200 मीटर रिकॉर्ड के साथ स्वैपिंग प्राप्त करेंगे, एक बार – gor

4

स्मृति में एक विशाल डेटा तालिका रखने के बजाय, मैं IDataReader को लागू करने का सुझाव दूंगा जो थोक प्रतिलिपि के रूप में डेटा को प्रस्तुत करता है। यह सब कुछ स्मृति में आगे रखने की आवश्यकता को कम करेगा, और इस प्रकार प्रदर्शन में सुधार करने के लिए काम करना चाहिए।

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