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

简介:

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

由于一些项目需要,字典管理模块需要批量录入数据,因此改善了我的《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();
                }
            }
        }

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

本文转自博客园伍华聪的博客,原文链接:使用事务操作SQLite数据批量插入,提高数据批量写入速度,源码讲解,如需转载请自行联系原博主。



目录
相关文章
|
2天前
|
SQL 存储 关系型数据库
数据储存数据库管理系统(DBMS)
【10月更文挑战第11天】
7 3
|
4天前
|
Web App开发 SQL 数据库
使用 Python 解析火狐浏览器的 SQLite3 数据库
本文介绍如何使用 Python 解析火狐浏览器的 SQLite3 数据库,包括书签、历史记录和下载记录等。通过安装 Python 和 SQLite3,定位火狐数据库文件路径,编写 Python 脚本连接数据库并执行 SQL 查询,最终输出最近访问的网站历史记录。
17 4
|
6天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置服务等,并与使用 RPM 包安装进行了对比,帮助读者根据需求选择合适的方法。编译源码安装虽然复杂,但提供了更高的定制性和灵活性。
47 2
|
8天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤
【10月更文挑战第7天】本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。同时,文章还对比了编译源码安装与使用 RPM 包安装的优缺点,帮助读者根据自身需求选择合适的方法。
19 3
|
8天前
|
SQL 存储 关系型数据库
添加数据到数据库的SQL语句详解与实践技巧
在数据库管理中,添加数据是一个基本操作,它涉及到向表中插入新的记录
|
11天前
|
SQL 监控 数据处理
SQL数据库数据修改操作详解
数据库是现代信息系统的重要组成部分,其中SQL(StructuredQueryLanguage)是管理和处理数据库的重要工具之一。在日常的业务运营过程中,数据的准确性和及时性对企业来说至关重要,这就需要掌握如何在数据库中正确地进行数据修改操作。本文将详细介绍在SQL数据库中如何修改数据,帮助读者更好
58 4
|
12天前
|
存储 关系型数据库 数据库
轻量级数据库的利器:Python 及其内置 SQLite 简介
轻量级数据库的利器:Python 及其内置 SQLite 简介
22 3
|
12天前
|
存储 人工智能 Cloud Native
云栖重磅|从数据到智能:Data+AI驱动的云原生数据库
阿里云瑶池在2024云栖大会上重磅发布由Data+AI驱动的多模数据管理平台DMS:OneMeta+OneOps,通过统一、开放、多模的元数据服务实现跨环境、跨引擎、跨实例的统一治理,可支持高达40+种数据源,实现自建、他云数据源的无缝对接,助力业务决策效率提升10倍。
|
13天前
|
关系型数据库 MySQL 数据库
使用Docker部署的MySQL数据库,数据表里的中文读取之后变成问号,如何处理?
【10月更文挑战第1天】使用Docker部署的MySQL数据库,数据表里的中文读取之后变成问号,如何处理?
38 3
|
12天前
|
消息中间件 数据采集 数据库
小说爬虫-03 爬取章节的详细内容并保存 将章节URL推送至RabbitMQ Scrapy消费MQ 对数据进行爬取后写入SQLite
小说爬虫-03 爬取章节的详细内容并保存 将章节URL推送至RabbitMQ Scrapy消费MQ 对数据进行爬取后写入SQLite
13 1