现有一个文本文件,大小为8M多,有大约25W行。每一行文本为一条数据,经过简单的字符串拆分就可以获取每个字段的值。但是,如果使用常规的SqlConnection和SqlCommand来执行插入的话,25W行数据大约会花去20分钟时间,这种效率是及其低下的。
如下代码:
string[] lines = File.ReadAllLines("CellPhoneNumber.txt", Encoding.Default);
string connString = @"Data Source = (local)\SqlExpress; Integrated Security = true; Initial Catalog = Test";
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
foreach (string line in lines)
{
string[] tempLine = line.Split('\t');
string PreFix = tempLine[0].Trim('\"');
string Area = tempLine[1].Trim('\"');
string Type = tempLine[2].Trim('\"');
string Code = tempLine[3].Trim('\"');
string cmdString = @"INSERT INTO T_CellPhoneLocation VALUES(@PreFix,@Area,@Type,@Code)";
using (SqlCommand cmd = new SqlCommand(cmdString, conn))
{
SqlParameter[] sqlParameters = new SqlParameter[]
{
new SqlParameter("@PreFix",PreFix),
new SqlParameter("@Area",Area),
new SqlParameter("@Type",Type),
new SqlParameter("@Code",Code)
};
cmd.Parameters.AddRange(sqlParameters);
cmd.ExecuteNonQuery();
}
}
但是如果使用SqlBulkCopy的话,效率会快上几百倍。但使用SqlBulkCopy需要先将待插入数据读取到内存的DataSet中,然后再一次性批量插入。
如下代码:
string connString = @"Data Source = (local)\SqlExpress; Integrated Security = true; Initial Catalog = Test";
DataTable dt = new DataTable();
dt.Columns.Add("PreFix");
dt.Columns.Add("Area");
dt.Columns.Add("Type");
dt.Columns.Add("Code");
string[] lines = File.ReadAllLines("CellPhoneNumber.txt", Encoding.Default);
foreach (string line in lines)
{
string[] tempLine = line.Split('\t');
DataRow dr = dt.NewRow();
dr["PreFix"] = tempLine[0].Trim('\"');
dr["Area"] = tempLine[1].Trim('\"');
dr["Type"] = tempLine[2].Trim('\"');
dr["Code"] = tempLine[3].Trim('\"');
dt.Rows.Add(dr);
}
using (SqlBulkCopy sbc = new SqlBulkCopy(connString))
{
sbc.DestinationTableName = "T_CellPhoneLocation";
sbc.ColumnMappings.Add("PreFix", "PreFix");
sbc.ColumnMappings.Add("Area", "Area");
sbc.ColumnMappings.Add("Type", "Type");
sbc.ColumnMappings.Add("Code", "Code");
sbc.WriteToServer(dt);
}
前者用时25min,后者用时4second
倍数相差; 375