.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
每件事到最后都是好事,如果不是好事,说明还没有到最后
=========================
作者:keepnode
博客地址:http://www.cnblogs.com/woaic
每件事到最后都是好事,如果不是好事,说明还没有到最后
=========================
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号