2016-06-23 241 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个插入,或每秒一次。这将填满日志页面,并将分摊成本记录刷新等待事务中的所有插入。与任何性能测试一样,确保您消除随机性,并预先分配数据库和日志,您不想击中数据库或日志增长事件。 –