`

C# 海量数据增加和修改

 
阅读更多

对于海量数据的插入和更新,ADO.NET确实不如JDBC做到好,JDBC有统一的模型来进行批操作.使用起来
非常方便:
 PReparedStatement ps = conn.prepareStatement("insert or update arg1,args2....");
 然后你就可以
 for(int i=0;i<1000000000000000;i++){
  ps.setXXX(realArg);
  .....
  ps.addBatch();
  if(i%500==0){ //假设五百条提交一次
   ps.executeBatch();
   //clear Parame Batch
  }
 }
 ps.executeBatch();
 
这样的操作不仅带来极度大的性能,而且非常方便.按说,ADO.NET中,要实现这样的功能,应该直接在Command接口中
或DataAdapter接口中提供Addbat和CommitBat的API,但ADO.NET的却并没有这样简单地实现,而是要求开发者通过
复杂的变通方法.
 对于大量的插入操作,可以利用一个空的DataTable加入要插入的行,达到一定数量提交后清空该表就行了,
实现起来并不算复杂:

 

DateTime begin = DateTime.Now;
string connectionString = ......;
using(SqlConnection conn = new SqlConnection(connectionString))...{
    conn.Open();
    SqlDataAdapter sd = new SqlDataAdapter();
    sd.SelectCommand = new SqlCommand("select devid,data_time,data_value from CurrentTest", conn);
    sd.InsertCommand = new SqlCommand("insert into CurrentTest (devid,data_time,data_value) "
                    + " values (@devid,@data_time,@data_value);", conn);
    sd.InsertCommand.Parameters.Add("@devid", SqlDbType.Char, 18, "devid");
    sd.InsertCommand.Parameters.Add("@data_time", SqlDbType.Char, 19, "data_time");
    sd.InsertCommand.Parameters.Add("@data_value", SqlDbType.Int, 8, "data_value");
    sd.InsertCommand.UpdatedRowSource = UpdateRowSource.None;
    sd.UpdateBatchSize = 0;

    DataSet dataset = new DataSet();
    sd.Fill(dataset);
    Random r = new Random(1000);
    for (int i = 0; i < 100000; i++) ...{
        object[] row = ...{"DEVID"+i,DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),r.Next(1,1000) };
        dataset.Tables[0].Rows.Add(row);
        if (i % 300 == 0) ...{
            sd.Update(dataset.Tables[0]);
            dataset.Tables[0].Clear();
        }
    }
    sd.Update(dataset.Tables[0]);
    dataset.Tables[0].Clear();
    sd.Dispose();
    dataset.Dispose();
    conn.Close();
  
}
TimeSpan ts = DateTime.Now - begin;
MessageBox.Show("ts = " + ts.TotalMilliseconds);

 

对于这个测试我插入10万条数据用时28秒.性能还算可圈可点.但是对于批量更新,搜遍全球的例子,都是把记录Fill到DataSet中然后牧举rows
来更新,就我这个小数据量的测试而言,把10万条数据Fill到DataSet中已经不能工作,如果是百万,千万如何操作?难道一定先把要批操作的记录
先获取到DataSet中?也就是我要更新哪些记录就要选查询这些记录?

 于是我仍然利用一个空的DataTable来加入要更新的记录:

 sd.SelectCommand = new SqlCommand("select devid,data_time,data_value from CurrentTest where 1=0", conn);
 //1=0的条件保证取一个空表.
 sd.UpdateCommand = new SqlCommand("update CurrentTest set data_time = @data_time,data_value = @data_value where devid = @devid", conn);
        sd.UpdateCommand.Parameters.Add("@data_time", SqlDbType.Char, 19, "data_time");
        sd.UpdateCommand.Parameters.Add("@data_value", SqlDbType.Int, 4, "data_value");
        sd.UpdateCommand.Parameters.Add("@devid", SqlDbType.Char, 20, "devid");
        sd.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
        sd.UpdateBatchSize = 0;

 for(int i=0;i<300;i++){
  ..............................
  dataset.Tables[0].Rows.Add(row);
 }
 sd.Update(dataset.Tables[0]);
 先更新300条试试,如果成功再循环更新所有记录,但提示插入操作需要InsertCommand,因为一个空表然后Add Row操作,这时RowState是Added,

如果这时Update到数据库,执行的就是插入操作而无法更新. 改成:
 for(int i=0;i<300;i++){
  ..............................

 row = {填入初始化的值};
  dataset.Tables[0].Rows.Add(row);
 }
 dataset.AcceptChanges();
 for(int i=0;i<300;i++){
  ..............................
  dataset.Tables[0].Rows[i][x] = "xxxxxxx";
  ..............................
 }
 sd.Update(dataset.Tables[0]);
 先在DataTable中插入数据,然后用AcceptChanges(),修改RowState为UnChanged,再修改表中数据希望改变UnChanged状态,即将

DataTable从Current状态改为Original,然后再对DataTable的Row进行更新,就能使

Update成功.但这样做确实不方便.


 调整思路,先从数据库中取200条(批更新的Size大小),直接得到一个Original的DataTable.

 sd.SelectCommand = new SqlCommand("select top 200 devid,data_time,data_value from CurrentTest", conn);
 DataSet dataset = new DataSet();
        sd.Fill(dataset);
 用这200个空间来放要更新的其它数据看看:
 
                    for (int i = 0; i < 100; i++)
                    {
                        dataset.Tables[0].Rows[i].BeginEdit();
                        dataset.Tables[0].Rows[i]["data_time"] = "2222-22-22 22:22:22";
                        dataset.Tables[0].Rows[i]["data_value"] = 100;
                        dataset.Tables[0].Rows[i]["devid"] = "DEVID"+(i+10000);//更新DEVID10000到DEVID10200的记录
                        dataset.Tables[0].Rows[i].EndEdit();
                    }
                    sd.Update(dataset.Tables[0]);
 OK,成功,哈哈.把要更新的数据不断往这个空间填,填满就提交,这样更新100000条数据只要几个循环就行了.


                  

 

DateTime begin = DateTime.Now;
            string connectionString = "";
            using(SqlConnection conn = new SqlConnection(connectionString))...{
                conn.Open();

                SqlDataAdapter sd = new SqlDataAdapter();
                sd.SelectCommand = new SqlCommand("select top 200 devid,data_time,data_value from CurrentTest", conn);

                DataSet dataset = new DataSet();
                sd.Fill(dataset);
                Random r = new Random(1000);

                sd.UpdateCommand = new SqlCommand("update CurrentTest "
                                + " set data_time = @data_time,data_value = @data_value where devid = @devid", conn);
                sd.UpdateCommand.Parameters.Add("@data_time", SqlDbType.Char, 19, "data_time");
                sd.UpdateCommand.Parameters.Add("@data_value", SqlDbType.Int, 4, "data_value");
                sd.UpdateCommand.Parameters.Add("@devid", SqlDbType.Char, 20, "devid");
                sd.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
                sd.UpdateBatchSize = 0;
                for (int count = 0; count < 100000;)
                ...{

                    for (int i = 0; i < 200; i++,count++)
                    ...{
                        dataset.Tables[0].Rows[i].BeginEdit();
                        dataset.Tables[0].Rows[i]["data_time"] = "2222-22-22 22:22:22";
                        dataset.Tables[0].Rows[i]["data_value"] = 100;
                        dataset.Tables[0].Rows[i]["devid"] = "DEVID"+count;
                        dataset.Tables[0].Rows[i].EndEdit();
                    }
                    sd.Update(dataset.Tables[0]);
                }
 

                dataset.Tables[0].Clear();
                sd.Dispose();
                dataset.Dispose


 

分享到:
评论

相关推荐

    淘特站内搜索引擎(C#版)

    前台搜索时,通过读取索引文件查询,避免了传统数据库查询在高并发及海量数据下的性能问题。因前台搜索不在连接数据库,为不希望数据库放到前台的特殊用户群体提供了数据快速查询解决方案。 +安装说明+ 本系统...

    深入云计算 MongoDB管理与开发实战详解pdf.part2

    第3章 文档的增加、修改及删除 3.1 插入并保存文档 3.1.1 插入的原理和作用 3.1.2 批量插入 3.2 删除文档 3.3 修改文档 3.3.1 整个文档的替换 3.3.2 使用修改器 3.3.3 upsert和save更新 ...

    深入云计算 MongoDB管理与开发实战详解pdf.part1

    第3章 文档的增加、修改及删除 3.1 插入并保存文档 3.1.1 插入的原理和作用 3.1.2 批量插入 3.2 删除文档 3.3 修改文档 3.3.1 整个文档的替换 3.3.2 使用修改器 3.3.3 upsert和save更新 ...

    国内外主流的三维GIS软件

     特点:NVP的多项核心技术,包括高效的海量空间数据管理技术、海量三维数据网络发布技术、地形、影像数据存储压缩技术、多精度地形、影像数据融合技术,处于国内外领先水平,在对于三维GIS系统最重要的海量数据支持...

    WPS表格和Excel分栏

    工作中需要对excel的海量数据进行分栏,百度经验里提供了一种手工操作方式不适用海量数据,于是自己动手开发,用C#调用office接口实现了该功能,后来又需要在wps表格中实现该功能,略做了修改,可在.net framework...

    AppFramework_V1.0

    NHibernate实现了纯对象化的ORMap,在屏蔽数据库差异、面向对象方面做的非常好,但在访问与操作海量数据时其性能表现较差,也不易实现复杂的查询统计功能。NHibernate适合那些数据量不大、性能要求不高、复杂度不高...

    AppFramework数据库访问组件_代码生成插件_V1.1.rar

    NHibernate实现了纯对象化的ORMap,在屏蔽数据库差异、面向对象方面做的非常好,但在访问与操作海量数据时其性能表现较差,也不易实现复杂的查询统计功能。NHibernate适合那些数据量不大、性能要求不高、复杂度不高...

    AppFramework_V1.0_New

    NHibernate实现了纯对象化的ORMap,在屏蔽数据库差异、面向对象方面做的非常好,但在访问与操作海量数据时其性能表现较差,也不易实现复杂的查询统计功能。NHibernate适合那些数据量不大、性能要求不高、复杂度不高...

    多门店4S.rar

    采用SQL-Server大型数据库,系统数据稳定安全,并实现了海量模糊查询,局域网即时通讯、条码识别等大量的高新科技 源码类型: B/S 开发环境: VS2012 + SQL2008 开发语言: C# 采用SQL-Server大型数据库,...

    风越ASP代码生成器2.8

    16、提供多种灵活翻页方案,用户可设置每页记录条数、上/下页、前/后N页、输入数字跳转到指定页面等,提高海量数据翻页速度 17、提供丰富的建站常用VB、JS函数库 ★ 18、更多扩展功能: 添加、修改页面在保存信息前...

    风越.Net代码生成器 [FireCode Creator] V1.3 精简版

    16、提供多种灵活翻页方案,用户可设置每页记录条数、上/下页、前/后N页、输入数字跳转到指定页面等,提高海量数据翻页速度 17、提供丰富的建站常用VB、JS函数库 ★ 18、更多扩展功能: 添加、修改页面在保存信息前...

    风越.net代码生成器 v3.5

    16、提供多种灵活翻页方案,用户可设置每页记录条数、上/下页、前/后N页、输入数字跳转到指定页面等,提高海量数据翻页速度 17、提供丰富的建站常用VB、JS函数库 ★ 18、更多扩展功能: 添加、修改页面在保存信息前...

    风越asp代码生成器 V3.5

    16、提供多种灵活翻页方案,用户可设置每页记录条数、上/下页、前/后N页、输入数字跳转到指定页面等,提高海量数据翻页速度 17、提供丰富的建站常用VB、JS函数库 ★ 18、更多扩展功能: 添加、修改页面在保存信息前...

    asp.net大型汽车4s店维修管理系统多门店版源码

    采用SQL-Server大型数据库,系统数据绝对稳定安全,并实现了海量模糊查询,局域网即时通讯、条码识别等大量的高新科技,并集成了短信群发等许多先进实用的新功能,并继承了完美软件操作方便、功能强大等的传统风格,...

    风越.net代码生成器v2.9

    16、提供多种灵活翻页方案,用户可设置每页记录条数、上/下页、前/后N页、输入数字跳转到指定页面等,提高海量数据翻页速度 17、提供丰富的建站常用VB、JS函数库 ★ 18、更多扩展功能: 添加、修改页面在保存信息前...

    WEB通用权限管理系统源码

    13.海量批量删除数据库,调用公共存储过程,参数,表明,主键 特点: UI:传统html css,美观 漂亮 大方 实用 js框架:jquery 系统大部分使用AJAX操作。大大提高了用户体验 功能描述: 1.支持N级菜单导航,菜单...

Global site tag (gtag.js) - Google Analytics