• 使用事务操作SQLite数据批量插入,提高数据批量写入速度,源码讲解


    SQLite数据库作为一般单机版软件的数据库,是非常优秀的,我目前单机版的软件产品线基本上全部替换Access作为优选的数据库了,在开发过程中,有时候需要批量写入数据的情况,发现传统的插入数据模式非常慢,几千条数据的写入或者更新可能需要好几分钟时间,而SqlServer则相同的操作可能几秒即可,有无更好的方法来提高它的响应速度呢?答案是有的,就是采用事务提交,默认SQLite的数据库插入操作,如果没有采用事务的话,它每次写入提交,就会触发一次事务操作,而这样几千条的数据,就会触发几千个事务的操作,这就是时间耗费的根源。本文通过详细代码介绍如何使用事务来提高整个批量插入数据的速度,并以实际的Winform开发框架中的字典管理模块的批量插入功能来进行介绍,通过前后速度的对比,使得事务操作提高响应速度更有说服力。

    为了提高响应速度,我这里使用了事务操作,整个事务操作是基于EnterpriseLibray类库的数据库操作,由于我已经在框架的基类中做了封装,因此我们这里看到整个处理过程即可。

    其中MyRegion里面的代码就是遍历每行的数据,构造数据字典对象和排序号,然后调用InsertDictData函数进行数据的录入。其中InsertDictData函数的代码是

    复制代码
            /// <summary>
            /// 使用事务参数,插入数据,最后统一提交事务处理
            /// </summary>
            /// <param name="dictData">字典数据</param>
            /// <param name="seq">排序</param>
            /// <param name="trans">事务对象</param>
            private void InsertDictData(string dictData, string seq, DbTransaction trans)
            {
                if (!string.IsNullOrWhiteSpace(dictData))
                {
                    DictDataInfo info = new DictDataInfo();
                    info.Editor = LoginID;
                    info.LastUpdated = DateTime.Now;
                    info.DictType_ID = this.txtDictType.Tag.ToString();
                    info.Name = dictData.Trim();
                    info.Value = dictData.Trim();
                    info.Remark = this.txtNote.Text.Trim();
                    info.Seq = seq;
    
                    bool succeed = BLLFactory<DictData>.Instance.Insert(info, trans);
                }
            }
    复制代码

    整个插入功能按钮的处理全部代码如下所示。

    复制代码
            private void btnOK_Click(object sender, EventArgs e)
            {
                string[] arrayItems = this.txtDictData.Lines;
                int intSeq = -1;
                int seqLength = 3;
                string strSeq = this.txtSeq.Text.Trim();
                if (int.TryParse(strSeq, out intSeq))
                {
                    seqLength = strSeq.Length;
                }
    
                if (arrayItems != null && arrayItems.Length > 0)
                {
                    DbTransaction trans = BLLFactory<DictData>.Instance.CreateTransaction();
                    if (trans != null)
                    {
                        try
                        {
                            #region MyRegion
                            foreach (string strItem in arrayItems)
                            {
                                if (this.radSplit.Checked)
                                {
                                    if (!string.IsNullOrWhiteSpace(strItem))
                                    {
                                        string[] dataItems = strItem.Split(new char[] { ',', ',', ';', ';', '/', '、' });
                                        foreach (string dictData in dataItems)
                                        {
                                            #region 保存数据
                                            string seq = "";
                                            if (intSeq > 0)
                                            {
                                                seq = (intSeq++).ToString().PadLeft(seqLength, '0');
                                            }
                                            else
                                            {
                                                seq = string.Format("{0}{1}", strSeq, intSeq++);
                                            }
    
                                            InsertDictData(dictData, seq, trans);
                                            #endregion
                                        }
                                    }
                                }
                                else
                                {
                                    #region 保存数据
                                    if (!string.IsNullOrWhiteSpace(strItem))
                                    {
                                        string seq = "";
                                        if (intSeq > 0)
                                        {
                                            seq = (intSeq++).ToString().PadLeft(seqLength, '0');
                                        }
                                        else
                                        {
                                            seq = string.Format("{0}{1}", strSeq, intSeq++);
                                        }
    
                                        InsertDictData(strItem, seq, trans);
                                    }
                                    #endregion
                                }
                            }
                            #endregion
    
                            trans.Commit();
                            ProcessDataSaved(this.btnOK, new EventArgs());
                            MessageDxUtil.ShowTips("保存成功");
                            this.DialogResult = DialogResult.OK;
                        }
                        catch (Exception ex)
                        {
                            trans.Rollback();
                            LogTextHelper.Error(ex);
                            MessageDxUtil.ShowError(ex.Message);
                        }
                    }
                }
            }
    复制代码

    上面的批量插入,经过前后的测试,2千条数据批量插入SQLite数据库,需要大概3~4分钟左右,如果采用了事务操作,则在1~2秒内写入完成,速度提高不知道多少倍。如果是操作数据比较多的,强烈建议使用事务进行操作,可以给客户很好的体验效果。

    如果嫌上面的代码复杂,可以看下面的讲解代码可能就明白了

    复制代码
            using (DbTransaction dbTrans = conn.BeginTransaction())
            {
                using (DbCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = "INSERT INTO MyTable(MyValue) VALUES(?)";
                    DbParameter Field1 = cmd.CreateParameter();
                    cmd.Parameters.Add(Field1);
                    for (int n = 0; n < 100000; n++)
                    {
                        Field1.Value = n + 100000;
                        cmd.ExecuteNonQuery();
                    }
                }
            }
    复制代码

    上面是一种比较简单原始的事务操作,如果批量插入数据,同样能够起到一样的效果。

  • 相关阅读:
    尽解powershell的workflow
    powershell玩转iis网站服务器
    Windows Terminal (Preview)治好了cmd,powershell的癌症
    博客园“NET Core 版博客系统”的运维浅见
    此贴告诉你:为啥shell脚本人,不建议学python
    关于revit的外部扩展存储
    Revit二次开发 屏蔽复制构件产生的重复类型提示窗
    xpath测试工具 xpath调试工具
    c# 防止重复运行 弹出已运行窗口并传递消息
    .NET APlayer播放器 demo
  • 原文地址:https://www.cnblogs.com/soundcode/p/12053979.html
Copyright © 2020-2023  润新知