`

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


 

分享到:
评论

相关推荐

    虚拟列表快速显示海量数据

    在IT行业中,尤其是在开发大型数据应用时,如何高效地处理和显示海量数据是一个常见的挑战。`DataGridView`控件是Windows Forms应用程序中常用的一种用于显示表格数据的组件,它提供了丰富的功能,包括排序、筛选和...

    C#海量源代码入门经典(第4版)

    《C#海量源代码入门经典(第4版)》是一本专为初学者设计的编程教程,它通过大量的实例代码帮助读者快速掌握C#编程语言的基础与进阶知识。本书的特点在于其“海量源代码”,提供了丰富的编程示例,使得学习者能够...

    C#中海量数据的批量插入和更新[顶].pdf

    在C#中处理海量数据的批量插入和更新是一项常见的任务,尤其是在大数据应用或者ETL(提取、转换、加载)流程中。尽管ADO.NET在某些方面可能不如JDBC提供那么直观和便捷的批量操作API,但它仍然提供了高效的方法来...

    基于数据库的海量GDF导航电子地图数据处理方法.pdf

    在处理这类数据时,面临的主要问题包括海量数据的存储、检索效率、数据格式的灵活性以及数据处理的性能等。GDF文件在定义上具有一定的灵活性,不同的数据供应商可能对同一要素有不同的字段定义。因此,处理GDF数据时...

    教案管理系统C#源码,可以运行SQL2008+VS2008

    这些案例可能涵盖变量声明、控制流、类和对象、接口、异常处理等多个方面,旨在帮助开发者深入理解C#语言,并能更好地阅读和修改源代码。 综上所述,这个教案管理系统不仅展示了C#在开发企业级应用中的实用性,也...

    基于C#的电子病历管理系统源码.zip

    4. 病历查询:通过患者ID、疾病类型等多种条件进行快速检索,C#的数据库访问技术(如ADO.NET)可以高效处理海量数据。 5. 报告生成:系统应能自动生成各类医疗报告,如诊断报告、治疗方案等,这需要C#的报表服务...

    Hospital_MIS(修正10月24)C# c/s医院管理系统

    此外,为了保证系统的稳定运行,通常会采用数据库管理系统(如SQL Server)来存储和管理海量的医疗数据,通过优化数据库设计和索引策略,提升查询速度和数据安全性。 总之,“Hospital_MIS(修正10月24)C# c/s医院...

    基于C#的三层架构的学生宿舍管理系统(源码+数据库).rar

    这些表之间的关系可能是一对一、一对多或多对多,通过合理设计数据库模式,可以有效地管理海量数据,支持高效的查询和更新操作。 业务逻辑层的实现是系统的核心部分,它处理各种业务规则,如新生入住、宿舍调整、...

    文件海量修改

    在IT行业中,"文件海量修改"通常涉及到大数据处理和自动化脚本编程,特别是当需要对大量文件进行统一的更改或更新时。以下是一些相关的知识点: 1. **批处理操作**:批处理是指一次性处理多个文件或任务的技术,...

    C# CS超市信息管理系统毕业设计(含源文件).docx

    通过关联规则分析,可以从海量数据中发现商品之间的购买关联性,为制定营销策略提供依据,避免盲目补货带来的资金浪费,提高经济效益。例如,通过分析顾客购物篮数据,可以发现某些商品经常一起被购买,从而优化商品...

    商品销售系统数据挖掘源程序+数据库+文档

    1. 数据挖掘:数据挖掘是从海量数据中发现有价值信息的过程,它包括预处理、模式发现和模式评估三个主要步骤。在这个系统中,数据挖掘主要关注于商品销售数据,如销售量、销售额、商品类别等,通过分析这些数据,...

    地理信息数据处理与质检软件的设计与开发.pdf

    随着计算机技术的快速发展,地理信息数据产品在信息化、海量化和规范化方面取得长足进步。地理信息系统(GIS)作为核心处理平台,其数据处理和质量检查的需求日益增长。特别是在基础测绘地理信息成果的生产过程中,...

    Hadoop(四)C#操作Hbase.doc

    总的来说,HBase是大数据处理领域的一个重要组件,通过C#等编程语言与HBase交互,能够有效地管理和处理海量数据。理解HBase的工作原理、存储机制以及操作流程,对于开发高效的大数据应用程序至关重要。

    基于数据挖掘的教育管理决策支持系统模型.pdf

    数据挖掘是信息时代的一个重要技术,它能够帮助我们从海量数据中提取有价值的信息,这对于管理和决策具有重要意义。在教育管理领域,数据挖掘技术的应用尤为重要,因为它能帮助教育管理者更好地理解教育环境,优化...

    c#网络爬虫程序设计.rar

    以上就是C#网络爬虫程序设计的一些核心知识点,通过这些知识,你可以创建出能适应不同需求的网络爬虫,从海量网页中提取有价值的信息。在实际开发中,还应关注法律法规,尊重网站的robots.txt文件,避免对目标网站...

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

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

    蜘蛛程序,最基本的网页抓取和html解析实力

    总的来说,“蜘蛛程序”是一个实用的工具,它展示了如何利用C#进行网页抓取和HTML解析,帮助用户从海量网页数据中获取有价值的信息。学习和理解这个项目,有助于提升你在网络数据获取领域的技能。

    FastDFS-Client

    5. **元数据操作**:可以获取或修改文件的元数据,如文件的属性、描述信息等。 在实际应用中,FastDFS-Client常用于互联网产品中的图片、视频等媒体资源的管理,例如电商平台的商品图片存储,社交平台的用户头像...

Global site tag (gtag.js) - Google Analytics