.net大批量数据的数据操作的性能消耗问题

公司的导入奖池的程序一直有问题,小数据量没有任何问题,但如果有2000条以上的数据导入时,就会很明显的感觉到很慢很慢。由于一直忙,没有找到好的解决方法。 今天终于算是找到好的解决方法了。 经过测试,本地数据导入内网SQL Server中5w多条数据,耗时为1秒中左右。飞一般的感觉。 解决方案的核心是:SqlBulkCopy 这是.net2.0新增的一个类,可以解决批量数据导入问题。使您可以用其他源的数据有效批量加载 SQL Server 表。 官方的解释: Microsoft SQL Server 提供一个称为 bcp 的流行的命令提示符实用工具,用于将数据从一个表移动到另一个表(表既可以在同一个服务器上,也可以在不同服务器上)。SqlBulkCopy 类允许编写提供类似功能的托管代码解决方案。还有其他将数据加载到 SQL Server 表的方法(例如 INSERT 语句),但相比之下 SqlBulkCopy 提供明显的性能优势。 使用 SqlBulkCopy 类只能向 SQL Server 表写入数据。但是,数据源不限于 SQL Server;可以使用任何数据源,只要数据可加载到 DataTable 实例或可使用 IDataReader 实例读取数据。 下面是我写的关于批量导入的核心代码。copy下来,作为备份学习。 [code lang="csharp"] /// <summary> /// 大批量数据 /// </summary> /// <param name="dt"></param> private void ToSqlServerExtension(DataTable dt) { string strCon = System.Configuration.ConfigurationManager.ConnectionStrings["GameTradingCon"].ToString(); //创建连接 SqlConnection sqlCon = new SqlConnection(strCon); sqlCon.Open(); DateTime beginTime = DateTime.Now; using (SqlBulkCopy sqlBC=new SqlBulkCopy(strCon))//用于执行大批量数据 { //一次批量插入的数据量 sqlBC.BatchSize = 1000; //超时之前操作完成所允许的秒数,如果超时则事务不会提交 ,数据将回滚,所有已复制的行都会从目标表中移除 sqlBC.BulkCopyTimeout = 60; //設定 NotifyAfter 属性,以便在每插入10000 条数据时,呼叫相应事件。 sqlBC.NotifyAfter = 1000; //设置要批量写入的表 sqlBC.DestinationTableName = "T_NPCgoActivityPrize"; //自定义的datatable和数据库的字段进行对应 sqlBC.ColumnMappings.Add("couponsId", "couponsId"); sqlBC.ColumnMappings.Add("couponsGroup", "couponsGroup"); sqlBC.ColumnMappings.Add("faceValue", "faceValue"); sqlBC.ColumnMappings.Add("prizeChannel", "prizeChannel"); sqlBC.ColumnMappings.Add("prizeName", "prizeName"); sqlBC.ColumnMappings.Add("prizeTypeDis", "prizeTypeDis"); sqlBC.ColumnMappings.Add("prizeSourceDis", "prizeSourceDis"); sqlBC.ColumnMappings.Add("prizeStarValidity", "prizeStarValidity"); sqlBC.ColumnMappings.Add("prizeEndValidity", "prizeEndValidity"); sqlBC.ColumnMappings.Add("useCondition", "useCondition"); sqlBC.ColumnMappings.Add("activityCreateChannel", "activityCreateChannel"); //批量写入数据 sqlBC.WriteToServer(dt); } sqlCon.Dispose(); DateTime endTime = DateTime.Now; //插入成功提示 Tools.Alert("导入SqlServer成功!请查看!执行sql开始时间:"+beginTime+",结束时间:"+endTime, this.Page); } private DataTable GetRealData(DataSet dsExcel) { DataTable dtResult = new DataTable(); dtResult.Columns.Add("couponsId"); dtResult.Columns.Add("couponsGroup"); dtResult.Columns.Add("faceValue"); dtResult.Columns.Add("prizeChannel"); dtResult.Columns.Add("prizeName"); dtResult.Columns.Add("prizeTypeDis"); dtResult.Columns.Add("prizeSourceDis"); dtResult.Columns.Add("prizeStarValidity"); dtResult.Columns.Add("prizeEndValidity"); dtResult.Columns.Add("useCondition"); dtResult.Columns.Add("activityCreateChannel"); try { for (int i = 0; i < dsExcel.Tables[0].Rows.Count; i++) { if (!string.IsNullOrEmpty(dsExcel.Tables[0].Rows[i].ItemArray[0].ToString())) { DataRow dr = dtResult.NewRow(); dr["couponsId"] =dsExcel.Tables[0].Rows[i].ItemArray[0].ToString(); dr["couponsGroup"] = txtPCH.Value.Trim(); dr["faceValue"] = "0"; dr["prizeChannel"] = ddlPrizes.SelectedValue; dr["prizeName"] = ddlPrizes.SelectedItem.Text; dr["prizeTypeDis"] = txtAwardType.Text; dr["prizeSourceDis"] = txtAwardFrom.Text; dr["prizeStarValidity"] = dbStart.Value; dr["prizeEndValidity"] = dbEnd.Value; dr["useCondition"] = txtUseCondtion.Value.Trim(); dr["activityCreateChannel"] = ddlActity.SelectedItem.Text; dtResult.Rows.Add(dr); } } } catch (Exception ex) { //失败提示 //Tools.Alert("导入SqlServer过程中发生错误!\n错误提示:" + ex.Message, this.Page); GameTradingByPublic.ExceptionLog.SetExceptionLog(ex); } return dtResult; } [/code]
写个博客不容易,请转载的时候备注下原文出处,谢谢
作者:keepnode
博客地址:http://www.cnblogs.com/woaic
每件事到最后都是好事,如果不是好事,说明还没有到最后
=========================
原文地址:https://www.cnblogs.com/woaic/p/3942847.html