运行结果如下:

插入100w条记录才8s多,是不是很溜。
打开Sqlserver Profiler跟踪,会发现执行的是如下语句:
insert bulk Product ([Id] UniqueIdentifier, [NAME] VarChar(50) COLLATE Chinese_PRC_CI_AS, [Price] Decimal(18,2))
方式三:使用TVPs(表值参数)插入数据
从sqlserver 2008起开始支持TVPs。创建缓存表ProductTemp ,执行如下SQL。
CREATE TYPE ProductTemp AS TABLE(
Id UNIQUEIDENTIFIER PRIMARY KEY,
NAME VARCHAR(50) NOT NULL,
Price DECIMAL(18,2) NOT NULL
)
执行完成之后,会发现在数据库CarSYS下面多了一张缓存表ProductTemp


可见插入100w条记录共花费了11秒多。
方式四:拼接SQL
此种方法在C#中有限制,一次性只能批量插入1000条,所以就得分段进行插入。
#region 方式四
static void InsertFour()
{
Console.WriteLine("采用拼接批量SQL插入的方式实现");
Stopwatch sw = new Stopwatch();
using (SqlConnection conn = new SqlConnection(StrConnMsg)) //using中会自动Open和Close 连接。
{
conn.Open();
sw.Start();
for (int j = 0; j < totalRow / getRow;j++ )
{
StringBuilder sb = new StringBuilder();
sb.Append("INSERT INTO Product(Id,Name,Price) VALUES");
using (SqlCommand cmd = new SqlCommand())
{
for (int i = 0; i < getRow; i++)
{
sb.AppendFormat("(newid(),'商品{0}',{0}),", j*i+i);
}
cmd.Connection = conn;
cmd.CommandText = sb.ToString().TrimEnd(',');
cmd.ExecuteNonQuery();
}
}
sw.Stop();
Console.WriteLine(string.Format("插入{0}条记录,共耗时{1}毫秒",totalRow,sw.ElapsedMilliseconds));
}
}
#endregion
运行结果如下:

我们可以看到大概花费了10分钟。虽然在方式一的基础上,性能有了较大的提升,但是显然还是不够快。
总结:大数据批量插入方式一和方式四尽量避免使用,而方式二和方式三都是非常高效的批量插入数据方式。其都是通过构建DataTable的方式插入的,而我们知道DataTable是存在内存中的,所以当数据量特别特别大,大到内存中无法一次性存储的时候,可以分段插入。比如需要插入9千万条数据,可以分成9段进行插入,一次插入1千万条。而在for循环中直接进行数据库操作,我们是应该尽量避免的。每一次数据库的连接、打开和关闭都是比较耗时的,虽然在C#中存在数据库连接池,也就是当我们使用using或者conn.Close(),进行释放连接时,其实并没有真正关闭数据库连接,它只是让连接以类似于休眠的方式存在,当再次操作的时候,会从连接池中找一个休眠状态的连接,唤醒它,这样可以有效的提高并发能力,减少连接损耗。而连接池中的连接数,我们都是可以配置的。










