日期:2014-05-16  浏览次数:20574 次

一些插入记录的方法比较

有同事写了个工具,对C#中,两种插入记录到SQL SERVER数据库的方法进行了比较,发现二者的性能相差天与地:


1、SqlBulkCopy,批量插入方式,5万条记录,仅花4秒

2、拼凑出一条条SQL语句,单条插入,5万条记录,耗时7分钟


//方式一,批量插入

            using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy((SqlConnection)connection)) 
            { 
                sqlBulkCopy.DestinationTableName = dataTable.TableName; 
                sqlBulkCopy.BatchSize = 100000; // 一次批量的插入的数据量 
                sqlBulkCopy.BulkCopyTimeout = 360;  
                // 自定义的DataTable和数据库的字段进行对应 
                foreach (DataColumn column in dataTable.Columns) 
                { 
                    sqlBulkCopy.ColumnMappings.Add(column.ColumnName, column.ColumnName); 
                } 
                sqlBulkCopy.WriteToServer(dataTable); 
            }

//方式二,单条插入

sqlString = "INSERT INTO Table2 (Int,Long,Float,Real,Date,NText,String1,String2,String3,String4) VALUES (@Int,@Long,@Float,@Real,@Date,@NText,@String1,@String2,@String3,@String4)"; 
                IDataParameter[] parameters = new IDataParameter[10]; 
                int count = Convert.ToInt32(txtCount.Text); 
                for (int i = 0; i < count; i++) 
                { 
                    parameters[0] = DBHelper.CreateParameter("Int", i); 
                    parameters[1] = DBHelper.CreateParameter("Long", i * 10); 
                    parameters[2] = DBHelper.CreateParameter("Float", i * 100 + 0.33); 
                    parameters[3] = DBHelper.CreateParameter("Real", i * 1000 + 0.999); 
                    parameters[4] = DBHelper.CreateParameter("Date", DateTime.Now); 
                    parameters[5] = DBHelper.CreateParameter("NText", DateTime.Now.ToLongTimeString()); 
                    parameters[6] = DBHelper.CreateParameter("String1", "String1_" + i.ToString()); 
                    parameters[7] = DBHelper.CreateParameter("String2", "String2_" + (i * 100 + 0.33).ToString()); 
                    parameters[8] = DBHelper.CreateParameter("String3", "String3_" + (i * 1000 + 0.999).ToString()); 
                    parameters[9] = DBHelper.CreateParameter("String4", "String4_" + DateTime.Now.ToShortDateString() + " _ " + DateTime.Now.ToLongDateString());
                    DBHelper.ExecuteNonQuery(connection, CommandType.Text, sqlString, parameters); 
                } 
                connection.Close();

为什么二者相差会这么大呢?

类似方式二的方式其实我也经常使用,数据库连接串在循环开始前已经打开,且只打开一次,循环结束再关闭,看起来无可挑剔。

不过我一直怀疑用代码来操作数据库,速度比不上直接在数据库里操作快。所以今天特地在数据库运行以下语句


3、方式三,直接在数据库运行循环插入

use [test]
go

TRUNCATE TABLE table2;
declare @i int
set @i = 0;
while @i < 50000
BEGIN
INSERT INTO [dbo].[Table2]
           ([Int]
           ,[Long]
           ,[Float]
           ,[Real]
           ,[Date]
           ,[NText]
           ,[String1]
           ,[String2]
           ,[String3]
           ,[String4])
     VALUES
           (0
           ,0
           ,0.33
           ,0.999
           ,'2012-10-10 15:23:01.433'
           ,'15:23:01'
           ,'String1_0                                         '
           ,'String2_0.33                                                                                        '
           ,'String3_0.999                                                                                                                                                                                           '
           ,'String4_2012-10-10 _ 2012年10月10日                                                                                                                                                                                                                            '
           );
           SET @i = @i + 1;
end;