上一篇随笔中,介绍了,基本的使用没什么问题了,那么开始数据的插入。

一 问题--无法容忍的插入效率

代码写入基本完成,然后开始测试。起初,插入数据的时候基本上是插入每次插入9组数据,看不出来数据插入的速度。

然后,当我每次插入600组数据的时候,我的天,这个速度真的无法容忍啊。

插入数据的方式是使用for循环,每次插入一组数据。

for (int i = ; i < DataArray.GetCount(); i ++)
{
progressDlg->ProGress.SetPos(i);
szQuery.Format("INSERT INTO %s VALUES ('%d','%0.2f','%0.5f','%0.5f','%0.1f','%0.5f','%0.5f','%0.2f','%0.2f','%0.2f')",strTemp,i+,DataArray.GetAt(i).L,DataArray.GetAt(i).x,DataArray.GetAt(i).y,DataArray.GetAt(i).Tc,DataArray.GetAt(i).u,DataArray.GetAt(i).v,DataArray.GetAt(i).X,DataArray.GetAt(i).Y,DataArray.GetAt(i).Z);
fTest = sqlite.DirectStatement(szQuery);
if (!fTest)
AfxMessageBox(_T("插入数据失败!"));
}

我的天,大概感受了一下,600组数据,最起码一分钟以上,而我原来使用文本记录的时候,开始数据少的时候,也不过一秒钟100组数据,可换成这SQLite,600组数据居然要一分多钟。

增加个时间来计下时间:

SYSTEMTIME timeStart;
SYSTEMTIME timeStop;
GetLocalTime(&timeStart);
for (int i = ; i < DataArray.GetCount(); i ++)
{
progressDlg->ProGress.SetPos(i);
szQuery.Format("INSERT INTO %s VALUES ('%d','%0.2f','%0.5f','%0.5f','%0.1f','%0.5f','%0.5f','%0.2f','%0.2f','%0.2f')",strTemp,i+,DataArray.GetAt(i).L,DataArray.GetAt(i).x,DataArray.GetAt(i).y,DataArray.GetAt(i).Tc,DataArray.GetAt(i).u,DataArray.GetAt(i).v,DataArray.GetAt(i).X,DataArray.GetAt(i).Y,DataArray.GetAt(i).Z);
fTest = sqlite.DirectStatement(szQuery);
if (!fTest)
AfxMessageBox(_T("插入数据失败!"));
}
GetLocalTime(&timeStop);
printf("\n开始时间 %d:%d:%d",timeStart.wMinute,timeStart.wSecond,timeStart.wMilliseconds);
printf("\n结束时间 %d:%d:%d",timeStop.wMinute,timeStop.wSecond,timeStop.wMilliseconds);
printf("\n用时%d毫秒\n\n",(timeStop.wMinute** + timeStop.wSecond* + timeStop.wMilliseconds)-(timeStart.wMinute** + timeStart.wSecond* + timeStart.wMilliseconds));

经过准确的计时,得到600组数据插入的时间是63024毫秒,我的天,再逗我吗。

二 解决方案  事务

经过查找资料,了解到,提升插入效率的方法,就是不要一条条的插入数据,启用一个事务,一起插入。

所谓”事务“就是指一组SQL命令,这些命令要么一起执行,要么都不被执行。在SQLite中,每调用一次sqlite3_exec()函数,就会隐式地开启了一个事务,如果插入一条数据,就调用该函数一次,事务就会被反复地开启、关闭,会增大IO量。如果在插入数据前显式开启事务,插入后再一起提交,则会大大提高IO效率,进而加数据快插入速度。
开启事务只需在上述代码的前后各加一句开启与提交事务的命令即可:
使用SQLite的API函数的话,就是这个样子
sqlite3_exec(db,"begin;",,,);
for(int i=;i<nCount;++i)
{
std::stringstream ssm;
ssm<<"insert into t1 values("<<i<<","<<i*<<","<<i/<<","<<i*i<<")";
sqlite3_exec(db,ssm.str().c_str(),,,);
}
sqlite3_exec(db,"commit;",,,);

那么使用SQLite3Wrapper的封装类该怎么办呢。

只需要插入前后增加一个Begin() 和 Commit()即可,就是这个样子:

sqlite.Commit();
GetLocalTime(&timeStop);
printf("\n开始时间 %d:%d:%d",timeStart.wMinute,timeStart.wSecond,timeStart.wMilliseconds);
printf("\n结束时间 %d:%d:%d",timeStop.wMinute,timeStop.wSecond,timeStop.wMilliseconds);
printf("\n用时%d毫秒\n\n",(timeStop.wMinute** + timeStop.wSecond* + timeStop.wMilliseconds)-(timeStart.wMinute** + timeStart.wSecond* + timeStart.wMilliseconds));
progressDlg->OnClose(); SYSTEMTIME timeStart;
SYSTEMTIME timeStop;
GetLocalTime(&timeStart);
sqlite.Begin();
for (int i = ; i < DataArray.GetCount(); i ++)
{
progressDlg->ProGress.SetPos(i);
szQuery.Format("INSERT INTO %s VALUES ('%d','%0.2f','%0.5f','%0.5f','%0.1f','%0.5f','%0.5f','%0.2f','%0.2f','%0.2f')",strTemp,i+,DataArray.GetAt(i).L,DataArray.GetAt(i).x,DataArray.GetAt(i).y,DataArray.GetAt(i).Tc,DataArray.GetAt(i).u,DataArray.GetAt(i).v,DataArray.GetAt(i).X,DataArray.GetAt(i).Y,DataArray.GetAt(i).Z);
fTest = sqlite.DirectStatement(szQuery);
if (!fTest)
AfxMessageBox(_T("插入数据失败!"));
}
sqlite.Commit();
GetLocalTime(&timeStop);
printf("\n开始时间 %d:%d:%d",timeStart.wMinute,timeStart.wSecond,timeStart.wMilliseconds);
printf("\n结束时间 %d:%d:%d",timeStop.wMinute,timeStop.wSecond,timeStop.wMilliseconds);
printf("\n用时%d毫秒\n\n",(timeStop.wMinute** + timeStop.wSecond* + timeStop.wMilliseconds)-(timeStart.wMinute** + timeStart.wSecond* + timeStart.wMilliseconds));

经过计时输出,600组数据输出的时间大概是329毫秒,这提升那不是一个等级的啊。当然,这个速度对我目前的数据来说,已经够用了。

MFC使用SQLite 学习系列 二:无法容忍的数据插入效率的更多相关文章

  1. MFC使用SQLite 学习系列 一: SQLITE_MISUSE错误

    一 为什么要选择SQLite 由于使用文本文件来记录测试数据,速度越来越慢的问题,经过园友推荐,使用了SQLite来进行数据的存储,再次感谢园友@LightSmaile. 关于这个问题,可以参考一下上 ...

  2. MyBatis学习系列二——增删改查

    目录 MyBatis学习系列一之环境搭建 MyBatis学习系列二——增删改查 MyBatis学习系列三——结合Spring 数据库的经典操作:增删改查. 在这一章我们主要说明一下简单的查询和增删改, ...

  3. Maven学习系列二(1-5)

    Maven学习系列二(1-5) 本文转自 QuantSeven 博客,讲解精炼易懂,适合入门,链接及截图如下 http://www.cnblogs.com/quanyongan/category/47 ...

  4. scrapy爬虫学习系列二:scrapy简单爬虫样例学习

    系列文章列表: scrapy爬虫学习系列一:scrapy爬虫环境的准备:      http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_00 ...

  5. DocX开源WORD操作组件的学习系列二

    DocX学习系列 DocX开源WORD操作组件的学习系列一 : http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_sharp_001_docx1.htm ...

  6. [转]ASP.NET MVC学习系列(二)-WebAPI请求 传参

    [转]ASP.NET MVC学习系列(二)-WebAPI请求 传参 本文转自:http://www.cnblogs.com/babycool/p/3922738.html ASP.NET MVC学习系 ...

  7. RabbitMQ学习系列二-C#代码发送消息

    RabbitMQ学习系列二:.net 环境下 C#代码使用 RabbitMQ 消息队列 http://www.80iter.com/blog/1437455520862503 上一篇已经讲了Rabbi ...

  8. .net reactor 学习系列(二)---.net reactor界面各功能说明

    原文:.net reactor 学习系列(二)---.net reactor界面各功能说明         安装了.net reactor之后,可以在安装目录下找到帮助文档REACTOR_HELP.c ...

  9. 图机器学习(GML)&图神经网络(GNN)原理和代码实现(前置学习系列二)

    项目链接:https://aistudio.baidu.com/aistudio/projectdetail/4990947?contributionType=1 欢迎fork欢迎三连!文章篇幅有限, ...

随机推荐

  1. <<Senium2自动化测试>>读书笔记一

    为进一步加强Python知识扩展和学习,在朋友的推荐下选择了<<Selenium2自动化测试实战>>,作者胡志恒,基于Python语言实现,以实例的方式详细讲解WebDrive ...

  2. Spring 4.x (三)

    1 Spring中加入DataSource并引入jdbc.properties 步骤: ①加入c3p0的jar包和mysql的驱动包 ②在src下新建jdbc.propertes文件 jdbc.dri ...

  3. Mysql基本命令二

    删除id>10的记录:delete from user where id>10; 设置user表的自增字段起始值为10:alter table user anto_increment=10 ...

  4. awk处理重复行错误分析

    [root@localhost ~]#cat 0712 YRSD2-1-11 YRSD2-2-18 YRSD1-1-8 YRSD1-1-18 YRSD1-1-20 YRSD1-1-25 YRSD1-2 ...

  5. Node.js在任意目录下使用express命令‘不是内部或外部命令’解决方法

    1.一开始我只能在nodejs全局目录下使用express命令建一个新的项目,建在其他任意一个目录命令行都会提示"不是内部或外部命令",导致目录会乱,目录如下. 2.尝试了一会,发 ...

  6. 《.NET 设计规范》第 9 章:常用的设计模式

    第 9 章:常用的设计模式 9.1 聚合组件 考虑为常用的特性域提供聚合组件. 要用聚合组件来对高层的概念(物理对象)进行建模,而不是对系统级的任务进行建模. 要让聚合组件的名字与众所周知的系统实体相 ...

  7. 树莓派小车By 树莓派爱好者ITJoker(通过C socket通信实现树莓派视频小车)(二)

    前面的方法可以参照(一)来配置GPIO口. 下面是代码...仅供参考,转载请注明出处. 1.  先输入以下指令,再复制代码,Ctrl+X  输入Y  回车  保存. sudo nano start.c ...

  8. HTTP就是这么简单

    为什么要学HTTP? 我们绝大多数的Web应用都是基于HTTP来进行开发的.我们对Web的操作都是通过HTTP协议来进行传输数据的. 简单来说,HTTP协议就是客户端和服务器交互的一种通迅的格式. H ...

  9. Spring-shiro源码陶冶-AuthorizingRealm用户认证以及授权

    阅读源码有助于陶冶情操,本文旨在简单的分析shiro在Spring中的使用 简单介绍 Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能 AuthorizingReal ...

  10. HDU [P3605] Escape

    二分图多重匹配 改进版的匈牙利,加入了一个cnt数组作为找到增广路的标志 本题有一个重要的优化见注释 #include <iostream> #include <cstdio> ...