2016-06-23 296 views
0

我的CSV文件的大小爲4GB,我需要將其導入SQL服務器。 我認爲它有超過2000萬行。如果有人能在一個小時內給我一個方法來做到這一點,我會非常感激。將大Csv文件導入數據庫

我已經在做什麼:

using (FileStream filestream = new FileStream(path, FileMode.Open, FileAccess.Read)) { 
     using (StreamReader reader = new StreamReader(filestream, Encoding.UTF8)) { 

      string line = ""; 
      bool isHeader = true; 
      int counter = 0; 

      while ((line = reader.ReadLine()) != null) { 

       if (isHeader) { 
        model.Columns = line.Split(new string[] { "\t" }, StringSplitOptions.RemoveEmptyEntries); 
        isHeader = false; 
        continue; 
       } else { 

        if (Settings.Default.RonudSet != 0) { 
         LoadInDB(indicator,RoundDecimals(line)); 
        } else { 
         LoadInDB(indicator, line); 
        } 
       } 
       cmd.ExecuteNonQuery(); 
       counter++; 
      } 
} 
      model.RowCount = counter; 
      model.ColumnsCount = model.Columns.Length; 
     } 
    } 
    return model; 
} 

我的數據庫上傳方法:

public void LoadInDB(char indicator, string key) { 

     using (SqlConnection conn = new SqlConnection(Settings.Default.DBconnection)) { 

      conn.Open(); 
      try { 

       SqlCommand cmd = new SqlCommand("dbo.LipperFilesTestingInsertFileRowKey", conn); 

       cmd.CommandType = CommandType.StoredProcedure; 

       cmd.Parameters.Add(new SqlParameter("@FileRowKey", SqlDbType.NVarChar, 100)); 
       cmd.Parameters["@FileRowKey"].Value = key; 

       cmd.Parameters.Add(new SqlParameter("@targetTableIndicator", SqlDbType.NVarChar, 100)); 
       cmd.Parameters["@targetTableIndicator"].Value = indicator; 

       cmd.ExecuteNonQuery(); 

      } catch (SqlException sqlExc) { 

       MyLog.WriteToLog(sqlExc.Message,MyLog.Messages.Error); 
      } 
     } 
    } 

回答

0
  1. 你不應該打開每次插入一行一次新的連接。這會破壞你的表現。在開始讀取文件並在最後關閉它之前打開連接。
  2. 使用交易。搜索SqlConnection.BeginTransaction。這將提高DB端的性能。如果沒有事務,SQL Server將提交每個插入,這是浪費。
  3. 考慮使用SQL Server的BULK INSERT功能刪除整個加載數據的方法。
+1

此外,可以通過數據集和dataadapter上傳數據。通常會減慢個別更新的是等待日誌刷新的時間,您需要對此進行說明。最簡單的解決方案是簡單的批量提交。例如。提交每1000個插入,或每秒一次。這將填滿日誌頁面,並將分攤成本記錄刷新等待事務中的所有插入。與任何性能測試一樣,確保您消除隨機性,並預先分配數據庫和日誌,您不想擊中數據庫或日誌增長事件。 –