启用事务操作,解决批量插入或更新sqlite,mssql等数据库耗时问题

        private void button1_Click(object sender, EventArgs e)
        {
            //Sqlite使用事务批量操作 极大的提高速度
            DateTime starttime = DateTime.Now;
            using (SQLiteConnection con = new SQLiteConnection(connStr))
            {
                con.Open();
                DbTransaction trans = con.BeginTransaction();//开始事务
                SQLiteCommand cmd = new SQLiteCommand(con);
                try
                {
                    cmd.CommandText = "INSERT INTO MyTable(username,useraddr,userage) VALUES(@a,@b,@c)";
                    for (int n = 0; n < 100000; n++)
                    {
                        cmd.Parameters.Add(new SQLiteParameter("@a", DbType.String)); //MySql 使用MySqlDbType.String
                        cmd.Parameters.Add(new SQLiteParameter("@b", DbType.String)); //MySql 引用MySql.Data.dll
                        cmd.Parameters.Add(new SQLiteParameter("@c", DbType.String));
                        cmd.Parameters["@a"].Value = "张三" + n;
                        cmd.Parameters["@b"].Value = "深圳" + n;
                        cmd.Parameters["@c"].Value = 10 + n;
                        cmd.ExecuteNonQuery();
                    }
                    trans.Commit();//提交事务
                    DateTime endtime = DateTime.Now;
                    MessageBox.Show("插入成功,用时" + (endtime - starttime).TotalMilliseconds);

                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

//MySql 事务批量提交 极大提交速度
try
{
    using (MySqlConnection con = new MySqlConnection(MySqlStr))
    {
    con.Open();
    DbTransaction trans = con.BeginTransaction();//开始事务  

    #region 防重复先删除
    //循环本地Sqlite数据库数据
    for (int i = 0; i < count; i++)
    {
        DataRow dr = ds.Tables[0].Rows[i];
        string sqlDelete = "delete from packect where proimei=@d";
        MySqlCommand cmd1 = new MySqlCommand(sqlDelete, con);
        cmd1.Parameters.Add(new MySqlParameter("@d", MySqlDbType.String));
        cmd1.Parameters["@d"].Value = dr["proimei"];
        cmd1.ExecuteNonQuery();
    }
    #endregion

    #region 新增数据
    //循环本地Sqlite数据库数据
    for (int i = 0; i < count; i++)
    {
        DataRow dr = ds.Tables[0].Rows[i];
        string sqlInsert = "insert into packect(proimei, prokg, proadddate) values(@a,@b,@c)";
        MySqlCommand cmd2 = new MySqlCommand(sqlInsert, con);
        cmd2.Parameters.Add(new MySqlParameter("@a", MySqlDbType.String));
        cmd2.Parameters.Add(new MySqlParameter("@b", MySqlDbType.Decimal));
        cmd2.Parameters.Add(new MySqlParameter("@c", MySqlDbType.DateTime));
        cmd2.Parameters["@a"].Value = dr["proimei"];
        cmd2.Parameters["@b"].Value = dr["prokg"];
        cmd2.Parameters["@c"].Value = dr["proadddate"];
        cmd2.ExecuteNonQuery();
    }
    #endregion

    trans.Commit();//提交事务
    DateTime endtime = DateTime.Now;
    MessageBox.Show("上传数据成功,用时" + (endtime - starttime).TotalMilliseconds + "毫秒!");
    //清空本地数据库
    SQLiteHelper.ExecuteNonQuery(connStr, "delete from table1", CommandType.Text);
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

    /*
        DataTable dt = new DataTable();
        //定义需要插入的字段,字段名需跟数据库字段保持一致
        dt.Columns.Add("username");
        dt.Columns.Add("useraddr");
        dt.Columns.Add("userage");
        for (int i = 0; i < 10000; i++)
        {
            dt.Rows.Add("张三" + i, "深圳" + i, i);
        }
        DateTime starttime = DateTime.Now;
        SqlBulkCopyInsert(dt, "mytable");
        DateTime endtime = DateTime.Now;
        Response.Write("插入成功,用时" + (endtime - starttime).TotalSeconds + "秒");
     */
    /// <summary>
    /// 使用SqlBulkCopy批量插入,只限SQLServer,超大数据量快速导入
    /// </summary>
    /// <param name="table">填充的DataTable,支持其它数据源,请看重载</param>
    /// <param name="tableName">数据库对应表名</param>
    public void SqlBulkCopyInsert(DataTable table, string tableName)
    {
        SqlBulkCopy sbc = new SqlBulkCopy(MSCL.Until.GetApp("SqlConnStr"));
        sbc.DestinationTableName = tableName;

        for (int i = 0; i < table.Columns.Count; i++)
        {
            sbc.ColumnMappings.Add(table.Columns[i].ColumnName, table.Columns[i].ColumnName);
        }
        sbc.WriteToServer(table);
    } 

    /// <summary>
    /// 使用SqlBulkCopy批量插入,只限SQLServer,超大数据量快速导入
    /// 缺点,没有返回行数
    /// </summary>
    /// <param name="table">填充的DataTable,支持其它数据源,请看重载</param>
    /// <param name="tableName">数据库对应表名</param>
    /// <param name="columns">插入表对应的列名集合</param>
    public void SqlBulkCopyInsert(DataTable table, string tableName, string[] columns)
    {
        SqlBulkCopy sbc = new SqlBulkCopy("接连字符串");
        sbc.DestinationTableName = tableName;
        foreach (string col in columns)
        {
            sbc.ColumnMappings.Add(col, col);
        }
        sbc.WriteToServer(table);
    }

    /// <summary>
    /// 多行插入,Connection/Command/DataAdapter看你连接的数据库类型
    /// 进行相应的替换即可
    /// </summary>
    /// <param name="ds">填充数据后的数据集</param>
    /// <returns>受影响行数</returns>
    public int MultyInsert(DataSet ds)
    {
        int result = 0;
        IDbConnection con = new OracleConnection("连接字符串");
        con.Open();
        IDbCommand cmd = new OracleCommand();
        cmd.CommandText = "Insert into Member(UserName,Password) values(@name,@password)";
        IDbDataParameter namePar = cmd.CreateParameter();
        namePar.ParameterName = "@name";
        namePar.SourceColumn = "UserName";
        namePar.SourceVersion = DataRowVersion.Original;
        namePar.DbType = DbType.String;
        cmd.Parameters.Add(namePar);

        IDbDataParameter passPar = cmd.CreateParameter();
        passPar.ParameterName = "@pass";
        passPar.DbType = DbType.String;
        passPar.SourceColumn = "Password";
        passPar.SourceVersion = DataRowVersion.Original;
        cmd.Parameters.Add(passPar);

        IDbDataAdapter adpt = new OracleDataAdapter();
        adpt.InsertCommand = cmd;
        try
        {
            result = adpt.Update(ds);
        }
        catch (Exception)
        {

            throw;
        }
        finally
        {
            con.Close();
        }
        return result;
    }  

/*
 * Oracle中非常强大快速的数据批量操作方法
*/
////引用
//using System.Data;
//using System.Data.OracleClient;
//using Oracle.DataAccess.Client; //Oracle自带数据访问组件 位置: $Oracle安装路径$/bin/Oracle.DataAccess.dll
//设置一个数据库的连接串
string connectStr = "User Id=scott;Password=tiger;Data Source=";
OracleConnection conn = new OracleConnection(connectStr);
OracleCommand command = new OracleCommand();
command.Connection = conn;
//到此为止,还都是我们熟悉的代码,下面就要开始喽
//这个参数需要指定每次批插入的记录数
int recc = 10000000;
command.ArrayBindCount = recc;
//在这个命令行中,用到了参数,参数我们很熟悉,但是这个参数在传值的时候
//用到的是数组,而不是单个的值,这就是它独特的地方
command.CommandText = "insert into dept values(:deptno, :deptname, :loc)";
conn.Open();
//下面定义几个数组,分别表示三个字段,数组的长度由参数直接给出
int[] deptNo = new int[recc];
string[] dname = new string[recc];
string[] loc = new string[recc];
// 为了传递参数,不可避免的要使用参数,下面会连续定义三个
// 从名称可以直接看出每个参数的含义,不在每个解释了
OracleParameter deptNoParam = new OracleParameter("deptno", OracleType.Int32);
deptNoParam.Direction =  ParameterDirection.Input;
deptNoParam.Value = deptNo;
command.Parameters.Add(deptNoParam);
OracleParameter deptNameParam = new OracleParameter("deptname", OracleType.VarChar);
deptNameParam.Direction = ParameterDirection.Input;
deptNameParam.Value = dname; command.Parameters.Add(deptNameParam);
OracleParameter deptLocParam = new OracleParameter("loc", OracleType.VarChar);
deptLocParam.Direction = ParameterDirection.Input;
deptLocParam.Value = loc;
command.Parameters.Add(deptLocParam);
//在下面的循环中,先把数组定义好,而不是像上面那样直接生成SQL
for (int i = 0; i < recc; i++)
{
    deptNo[i] = i;
    dname[i] = i.ToString();
    loc[i] = i.ToString();
}
//这个调用将把参数数组传进SQL,同时写入数据库
command.ExecuteNonQuery();
时间: 2024-08-26 04:01:17

启用事务操作,解决批量插入或更新sqlite,mssql等数据库耗时问题的相关文章

Hibernate批处理操作优化 (批量插入、更新与删除)

问题描述 我开发的网站加了个新功能:需要在线上处理表数据的批量合并和更新,昨天下午发布上线,执行该功能后,服务器的load突然增高,变化曲线异常,SA教育了我一番,让我尽快处理,将CPU负载降低. 工作所需,我经常要写些程序批量处理数据,每次执行几十万数据处理的时候,我机子的CPU都会飙高,而且数据处理速度会越来越慢.比如第一个1W条要5分钟,第二个1W条就要10分钟,要干其他事情的时候机子也卡的不行,只能等着处理完数据. 其实我一直认为是数据量太大,从来不认为是程序问题,所以一直没怎么关注过.

C#使用SqlDataAdapter 实现数据的批量插入和更新

近日由于项目要求在需要实现中型数据的批量插入和更新,晚上无聊,在网上看到看到这样的一个实现方法,特摘抄过来,以便以后可能用到参考. 一.数据的插入 DateTime begin = DateTime.Now; string connectionString = ......; using(SqlConnection conn = new SqlConnection(connectionString)){ conn.Open(); SqlDataAdapter sd = new SqlDataAd

Asp.net QueryString批量插入和更新

public static string InsertOrUpdateQueryString(string[] keys, string[] values) { return InsertOrUpdateQueryString(System.Web.HttpContext.Current.Request, keys, values); } public static string InsertOrUpdateQueryString(System.Web.HttpRequest request,

java批量插入或更新的问题

在批量插入或者更新中,setXXX的时候字段类型必须一致.例如:在普通sql中 pstmt8.setBigDecimal(j ,xxx);可以写成pstmt8.setString(j,xxx.toString()); 但在批量插入时必须写成pstmt8.setBigDecimal(j,xxx);否则批处理会报提交中至少有一条不成功的问题.折腾一下午,终于搞好了.顺便记下来,方便参考.

Set,Sorted Set相关命令操作,批量插入及管道,事务

Set SADD key member [member ...] 向key指定的set集合添加成员,次集合是排重的,从2.4版本后才支持添加多个如果key不存在则创建key以及set集合返回当前操作成功添加的成员数量,不是所有的成员数量SMOVE source destination member把key为source的set中值为member的成员移动到key为destination的set集合中该操作是原子操作如果source不存在或者member不存在source中,则返回0?否则返回1S

MyBatis动态批量插入、更新Mysql数据库的通用实现方案

一.业务背景 由于需要从A数据库提取大量数据同步到B系统,采用了tomikos+jta进行分布式事务管理,先将系统数据源切换到数据提供方,将需要同步的数据查询出来,然后再将系统数据源切换到数据接收方,进行批量的插入和更新操作, 关于数据源的切换可以参考之前的文章<spring+springMVC+Mybatis架构下采用AbstractRoutingDataSource.atomikos.JTA实现多数据源灵活切换以及分布式事务管理> 二.批量插入的具体实现 1.查询需要同步的数据: @Aut

批量插入或更新数据

/// <summary>        /// 大数据单表批量插入,带事务        /// </summary>        /// <param name="keepID"></param>        /// <param name="tableName"></param>        /// <param name="dt"></para

Qt SQLite 批量插入优化(SQLite默认将每条语句看成单独的事务)good

使用SQLite存储数据时发现插入速度太慢,程序跑了将近五分钟才插入了不到三千条.上网查资料才发现,SQLite这种文件数据库与MySql机制不一样,每条事务都有打开和关闭文件的步骤,SQLite默认将每条语句看成单独的事务.当我逐条插入数据时,就会出现大量的文件IO操作,效率自然不高.需要将多个插入操作放到一个事务中,就可以显著提升插入效率. QT中使用事务的方法如下: QSqlDatabase app_database;// 设置数据库参数// ...app_database.transac

sql server中批量插入与更新两种解决方案分享(存储过程)

转自http://www.shangxueba.com/jingyan/1940447.html 1.游标方式 复制代码代码如下: DECLARE @Data NVARCHAR(max) SET @Data='1,tanw,2,keenboy' --Id,Name DECLARE @dataItem NVARCHAR(100) DECLARE data_cursor CURSOR FOR (SELECT * FROM split(@Data,';')) OPEN data_cursor FETC