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

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

代码写入基本完成,然后开始测试。起初,插入数据的时候基本上是插入每次插入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. 华人开创NTP网络授时服务器成功投运世界级超大工程港珠澳大桥

    华人开创NTP网络授时服务器成功投运世界级超大工程港珠澳大桥 本文由北京华人开创公司提供请勿转载 2017年12月中旬,我华人开创生产研发的NTP网络授时服务器成功投运世界级超大工程港珠澳大桥,为这个 ...

  2. servlet 监听器分类

    http://blog.csdn.net/cxg200888/article/details/77894842

  3. IO (三)

    1 转换流 1.1 InputStreamReader 1.1.1 InputStreamReader简介 InputStreamReader是字节流通向字符流的桥梁.它使用指定的charset读取字 ...

  4. C# 多线程复习笔记

    编码的日子其实也有一段时间了,但是,作为一个客户端程序,因为自己是做游戏开发的,一直没有对线程这个概念比较模糊吧. 记录下线程的整理学习路线.原文:http://www.cnblogs.com/min ...

  5. float 的不确定性

    很多时候,大家都知道,浮点型这个东西,本身存储就是一个不确定的数值,你永远无法知道,它是 0 = 0.00000000000000123 还是 0 = 0.00000000000999这样的东西.也许 ...

  6. root cause org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null, "XXX")

    在执行一个查询语句的时候,mybatis报错:root cause org.apache.ibatis.ognl.OgnlException: source is null for getProper ...

  7. NOIP 2017 day -1 杂记

    我几乎要崩溃了. 写任何板子都是第一遍一定写不对,后来发现是傻逼性错误. 好奇怪的,这些东西明明我都会,为什么现在我都忘了? 很烦.现在心里特别乱,写什么都写不下去. 可能我是真的无法放心这次的比赛. ...

  8. Google Chrome 圆形进度条

    Conmajia © 2012 Updated on Feb. 21, 2018 Google Chrome 的圆形进度条. Demo 功能 显示百分比(0-100).如果进度值达到 100%,则将闪 ...

  9. shell 脚本中执行SQL语句 -e "..."

    /usr/local/mysql/bin/mysql -uroot -p123456 -e " use faygo source faygo.sql select * from devqui ...

  10. 阿里云CentOS使用iptables禁止某IP访问

    在CentOS下封停IP,有封杀网段和封杀单个IP两种形式.一般来说,现在的攻击者不会使用一个网段的IP来攻击(太招摇了),IP一般都是散列的.于是下面就详细说明一下封杀单个IP的命令,和解封单个IP ...