Ado.net 大批量批量数据处理

suqifeng 2013-01-20 08:58:18
Ado.net 大批量同时处理 数据
用事物来处理 好像有点慢 ..
...全文
347 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
suqifeng 2013-01-24
  • 打赏
  • 举报
回复
对于海量数据的插入和更新,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中?也就是我要更新哪些记录就要选查询这些记录?
suqifeng 2013-01-24
  • 打赏
  • 举报
回复
http://www.cnblogs.com/Seabiscuit/archive/2010/05/25/1743341.html 我在博客园找到的 不知道他这样做 的效果怎样
吉普赛的歌 2013-01-22
  • 打赏
  • 举报
回复
引用 9 楼 suqifeng 的回复:
引用 8 楼 yenange 的回复:引用 7 楼 suqifeng 的回复:C# code?12345678910111213141516171819202122232425262728293031323334 /// <summary> /// 用事务执行多个Cmd /// </summary> /// <pa……
涉及到数据库的部分,越是复杂越要用sql来解决。 你新增记录, 写一个存储过程不行吗? 把新增时的字段作为参数传进来, 其它的所有操作, 放在存储过程里来做, 速度快很多,而且不易出错。  你之所以用C#, 只是没有领略到写sql 的方便与好处。
卧_槽 2013-01-22
  • 打赏
  • 举报
回复
数据量太大,还是用nosql吧
suqifeng 2013-01-21
  • 打赏
  • 举报
回复
引用 8 楼 yenange 的回复:
引用 7 楼 suqifeng 的回复:C# code?12345678910111213141516171819202122232425262728293031323334 /// <summary> /// 用事务执行多个Cmd /// </summary> /// <param name="LsCmd">要执……
批量删除 修改 可以用
 DELETE Tb_Name WHERE ID IN()
 UPDATE Tb_Name SET [TYPE]='X' WHERE ID IN()
----------------------------------------------------- 如果我新增 涉及到多个表 那样用C# 的事物来处理 应该没关系吧 最多十几个 sql SqlCommand
吉普赛的歌 2013-01-21
  • 打赏
  • 举报
回复
引用 7 楼 suqifeng 的回复:
C# code?12345678910111213141516171819202122232425262728293031323334 /// <summary> /// 用事务执行多个Cmd /// </summary> /// <param name="LsCmd">要执行的cmd集合-ListSqlComma……
比如说执行删除, 如果用循环执行上千个删除, 当然慢啦! 但如果 delete from table1 where id in ( xx,yy,zz,.... ) --逻辑删除, 类似: update Deleted =1 where id in ( xx,yy,zz,.... ) 这样的话, 速度不就上来了? 根本不是一个级别。  所以, 凡是关系到sql 的东西, 不要用C#去解决, 想办法直接用sql 解决才是王道!
suqifeng 2013-01-21
  • 打赏
  • 举报
回复


        /// <summary>
        ///  用事务执行多个Cmd
        /// </summary>
        /// <param name="LsCmd">要执行的cmd集合-ListSqlCommand</param>
        /// <returns>返回是否执行成功-bool</returns>
        public static bool ExecuteTransaction(List<SqlCommand> LsCmd)
        {
            bool brt = false;
            SqlConnection con = GetCon();
            OpenCon(con);
            SqlTransaction tran = con.BeginTransaction();
            try
            {
                foreach (SqlCommand cmd in LsCmd)
                {
                    cmd.Connection = con;
                    cmd.Transaction = tran;
                    cmd.ExecuteNonQuery();
                }
                tran.Commit();
                brt = true;
            }
            catch (Exception err)
            {
                tran.Rollback();
                brt = false;
                throw new Exception(err.Message);
            }
            finally
            {
                CloseCon(con);
            }
            return brt;
        }
我在BLL层就会 传一个List<SqlCommand> 如果客户处理数据量大的话 有上千个吧 我自己在想 这样效率肯定不高 怎样进行优化 提高效率 减少服务器负担
zhengnan2012 2013-01-21
  • 打赏
  • 举报
回复
可以不用事务,就是怎你用到的环境,和数据的完整性是否高,如果不高可以不用啊。
吉普赛的歌 2013-01-21
  • 打赏
  • 举报
回复
还有, 你所谓的事务, 是在C# 中写的, 还是在 存储过程中写的? 如果是在C#中构造的事务, 慢是有点可能, 但在存储过程中的事务基本上是没可能的。  建议你直接用存储过程写完所有的业务逻辑(当然,还是用到事务)。
吉普赛的歌 2013-01-21
  • 打赏
  • 举报
回复
给个标准吧? 你现在需要几秒?你想达到至少多少秒以内?
suqifeng 2013-01-21
  • 打赏
  • 举报
回复
比如新增一条数据 我要新增 三个表的数据 修改一个表的数据 还有一个批量修改状态 一个表修改字段 200多条 另外两个表 新增 400多条 这样用什么方法处理比较合适 或者更多 ..
  • 打赏
  • 举报
回复
假设是sql server,如果你不显式地编写事务代码,SQL SERVER会默认地为会话中每一个sql语句启动一个事务。所以说,此时不存在“没有使用事务的”可能性。 你是如何显式地编写事务代码的?有必要编写这个代码吗?如果有必要,那么是否能够每500条记录放到一个事务中(而不是所有)?一般来说,几百条放在一个事务中,是最快的。
caojiaqian1 2013-01-21
  • 打赏
  • 举报
回复
你好 .. 我用ADO.NET 2.0 TO SQL 2005 Insert , update , delete 一百万条数据 需要 15 - 12 秒 . 双核CPU.. 2G内存.还行吧.表字段共计10个 ... 关键不在于ADO.NET ..而在人 ..

1,979

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 其他语言讨论
社区管理员
  • 其他语言社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧