C#频繁对数据库操作,性能问题
C# 频繁对数据库操作,性能问题
1、与数据库交互,创建⼀次连接,必然影响性能。
Connection.open(); 打开以后⽤完关闭Connection.close();就算你只打开⼀次连接,⽤过多以后,再close;
性能会⽐前者快很多倍,如果只有100条数据以内,那也过得去;如果数据量达到1000,那这样性能也提升不上来;
Select、Insert、Update等语句,字符串连接起来,做⼀次执⾏。效率要可观多了。如下:
command.Excu(Insert into Table(a,b,c)Values(1,2,3);Insert into Table(a,b,c)Values(1,2,3);Insert into Table(a,b,c)Values(1,2,3););
2、SqlBulkCopy
在做⼤批量数据插⼊的时候,如果⽤Insert into ... values (...)这种⽅式的话效率极低,批量插⼊⽅法。
View Code
1private static long SqlBulkCopyInsert()
2 {
3 Stopwatch stopwatch = new Stopwatch();
4 stopwatch.Start();
5 DataTable dataTable = GetTableSchema();
6string passportKey;
7for (int i = 0; i < count; i++)
8 {
9 passportKey = Guid.NewGuid().ToString();
10 DataRow dataRow = dataTable.NewRow();
11 dataRow[0] = passportKey;
12 dataTable.Rows.Add(dataRow);
13 }
14 SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(connectionString);
15 sqlBulkCopy.DestinationTableName = "Passport";
16 sqlBulkCopy.BatchSize = dataTable.Rows.Count;
17 SqlConnection sqlConnection = new SqlConnection(connectionString);
18 sqlConnection.Open();
19if (dataTable!=null && dataTable.Rows.Count!=0)
20 {
21 sqlBulkCopy.WriteToServer(dataTable);
22 }
23 sqlBulkCopy.Close();
24 sqlConnection.Close();
25 stopwatch.Stop();
26return stopwatch.ElapsedMilliseconds;
27 }
28
29
使⽤SqlBulkCopy类进⾏数据插⼊其原理是采⽤了SQL Server的BCP协议进⾏数据的批量复制。这⾥我们先要建好⼀个DataTable(最好是通过DataAdapter来灌数据得到,
因为这样出来的DataTable就已经有跟数据表相同的列定义,可以免去之后Mapping Column的步骤),把要插⼊的数据加进这个DataTable中,然后⽤SqlBulkCopy的实例来插
⼊到数据库中。经过测试,SqlBulkCopy⽅法⽐直接⽤Sql语句插⼊数据的效率⾼出将近25倍。
另外批量导⼊SQL、MYSQL等数据是同样的for循环,使⽤拼出来的sql或者使⽤参数的⽅式传递或者使⽤事务等不同⽅式的传递效率都不同。如果不使⽤SqlBulkCopy的⽅
式的话,我测试下来做快递是⽤⼀次事务来操作为最快。因为10000次的循环如果是每次提交,那么都有链接和停⽌数据库的操作,或者说他包含了1000次的⼩事务处理。如果
外⾯就⼀个事务的话效率肯定会⾼。
其它⽅案⽹上参考:
View Code
技术⽅案⼀:sql 字符串转数组
利⽤数据库访问类调⽤存储过程,利⽤循环逐条插⼊。很明显,这种⽅式效率并不⾼。
技术⽅案⼆:
由于是考虑到⼤数据量的批量插⼊,于是想到了ADO.NET2.0的⼀个新的特性:SqlBulkCopy。有关这
个的性能,很早之前我亲⾃做过性能测试,效率⾮常⾼。这也是我推荐的技术⽅案。
技术⽅案三:
利⽤SQLServer2008的新特性--表值参数(Table-Valued Parameter)。表值参数是SQLServer2008才有的⼀个新特性,使⽤这个新特性,我们可以把⼀个表类型作为参数传递到函数或存储过程⾥。不过,它也有⼀个特点:表值参数在插⼊数⽬少于技术⽅案四:
对于单列字段,可以把要插⼊的数据进⾏字符串拼接,最后再在存储过程中拆分成数组,然后逐条插⼊。查了⼀下存储过程中参数的字符串的最⼤长度,然后除以字段的长度,算出⼀个值,很明显是可以满⾜要求的,只是这种⽅式跟第⼀种⽅式⽐起技术⽅案五:
考虑异步创建、消息队列等等。这种⽅案⽆论从设计上还是开发上,难度都是有的。
优势对⽐:
⽅案⼀的效率最低,需要多次更新数据库,⽅案四与⽅案⼀原理相同,只是将处理放到了存储过程中,且在参数传⼊前后需进⾏拼接和拆分,操作⽐较⿇烦。⽤SQL2008数据库时推荐使⽤⽅案四。
对⽐⽅案⼀、⼆、三,技术⽅案⼆的优势还是蛮⾼的。⽆论是从通⽤性还是从性能上考虑,都应该是优
先被选择的,另外它的技术复杂度要⽐技术⽅案三要简单⼀些,设想我们把所有表都创建⼀遍表值类型,⼯作量还是很⼤。
因此推荐⼤家使⽤第⼆种技术⽅案。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论