最近做到的项目涉及一个大数据量缓存重传,其中要用到的sqlite技术,把自己的学习心得整理了一下。

SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库管理系统来讲,它的处理速度比他们都快。SQLite数据库由于其简单、灵活、轻量、开源,已经被越来越多的被应用到中小型应用中。因此在许多软件中例如(QQ,微信)等许多软件中都有广泛应用。

sqlite应用蛮广泛的,小到app应用,大到服务器缓存。不同的插入方法有不同的优劣,在实际开发过程中,不要一味的追求快,而忽视了安全性。下面我就介绍几种我在这段学习过程中所了解的插入方式。

慢插入-暴力插入

调用sqlite3_exec()函数,会隐式地开启了一个事务,其次,sqlite3_exec() 是sqlite3_perpare(),sqlite3_step(),  sqlite3_finalize()的一个结合,每调用一次这个函数,就会重复的执行这三条语句,对于相同的语句,其中sqlite3_perpare相当于编译sql语句,如果语句相同且重复操作,就会增加很多重复操作。如果插入一条数据,就调该函数一次,事务就会被反复地开启、关闭,会增大IO量。所以当大批量数据插入时,此方法简直无法忍受。

事务插入-显示的开启事务

所谓”事务“就是指一组SQL命令,这些命令要么一起执行,要么都不被执行。如果在插入数据前显式开启事务,插入后再一起提交,

则会大大提高IO效率,进而加数据快插入速度

同步关闭模式-synchronous = OFF

当synchronous设置为FULL, SQLite数据库引擎在紧急时刻会暂停以确定数据已经写入磁盘。这使系统崩溃或电源出问题时能确保数据库在重起后不会损坏。FULL synchronous很安全但很慢。

当synchronous设置为NORMAL, SQLite数据库引擎在大部分紧急时刻会暂停,但不像FULL模式下那么频繁。 NORMAL模式下有很小的几率(但不是不存在)发生电源故障导致数据库损坏的情况。但实际上,在这种情况 下很可能你的硬盘已经不能使用,或者发生了其他的不可恢复的硬件错误。

当设置为synchronous OFF时,SQLite在传递数据给系统以后直接继续而不暂停。若运行SQLite的应用程序崩溃, 数据不会损伤,但在系统崩溃或写入数据时意外断电的情况下数据库可能会损坏。另一方面,在synchronous OFF时 一些操作可能会快50倍甚至更多。在SQLite 2中,缺省值为NORMAL.而在3中修改为FULL。

执行前准备-sqlite3_prepare_v2

此方法就是“执行准备”(类似于存储过程)操作,即先将SQL语句编译好,然后再一步一步(或一行一行)地执行。如果采用前者的话,就算开起了事务,SQLite仍然要对循环中每一句SQL语句进行“词法分析”和“语法分析”,这对于同时插入大量数据的操作来说,简直就是浪费时间。因此,要进一步提高插入效率的话,就应该使用此方法

测试结果展示

附上源代码

 extern "C"
{
#include "sqlite3.h"
}; #include<sstream>
#include <string>
#include <iostream>
#include <stdlib.h>
#include <ctime>
#include<windows.h> #define MAX_TEST_COUNT 200 using namespace std; int main()
{
char cmdCreatTable[] = "create table SqliteTest (id integer , x integer , y integer, weight real)" ;
sqlite3* db = NULL;
char * errorMessage = NULL;
int iResult = sqlite3_open("SqliteTest.db", &db);
do
{
if (SQLITE_OK != iResult)
{
cout<<"创建InsertTest.db文件失败"<<endl;
break;
} sqlite3_exec(db,"drop table if exists SqliteTest",,,); iResult = sqlite3_exec(db, cmdCreatTable, NULL, NULL, &errorMessage);
if (SQLITE_OK != iResult)
{
cout<<"创建表SqliteTest失败"<<endl;
break;
}
DWORD timeStart;
DWORD timeStop;
timeStart = GetTickCount();
for (int i = ; i< MAX_TEST_COUNT; ++i)
{
stringstream ssm;
ssm<<"insert into SqliteTest values("<<i<<","<<i*<<","<<i/<<","<<i*i<<")";
iResult = sqlite3_exec(db,ssm.str().c_str(),,,);
}
timeStop = GetTickCount();
cout<< "直接Insert"<<MAX_TEST_COUNT<<"条数据操作执行时间" << timeStart<<"结束时间:"<<timeStop<<"共耗时:"<<timeStop-timeStart<<"ms"<<endl; timeStart = GetTickCount();
sqlite3_exec(db,"PRAGMA synchronous = OFF; ",,,);
for(int i = MAX_TEST_COUNT; i < MAX_TEST_COUNT*; ++i)
{
stringstream ssm;
ssm<<"insert into SqliteTest values("<<i<<","<<i*<<","<<i/<<","<<i*i<<")";
sqlite3_exec(db,ssm.str().c_str(),,,);
}
timeStop = GetTickCount(); cout<< "同步写关闭+直接Insert"<<MAX_TEST_COUNT<<"条数据操作执行时间" << timeStart<<"结束时间:"<<timeStop<<"共耗时:"<<timeStop-timeStart<<"ms"<<endl; timeStart = GetTickCount();
sqlite3_exec(db,"PRAGMA synchronous = FULL; ",,,);
sqlite3_exec(db,"begin;",,,);
for(int i= MAX_TEST_COUNT*; i< MAX_TEST_COUNT*; ++i)
{
stringstream ssm;
ssm<<"insert into SqliteTest values("<<i<<","<<i*<<","<<i/<<","<<i*i<<")";
sqlite3_exec(db,ssm.str().c_str(),,,);
}
sqlite3_exec(db,"commit;",,,);
timeStop = GetTickCount();
cout<< "事务Insert"<<MAX_TEST_COUNT<<"条数据操作执行时间"<< timeStart<<"结束时间:"<<timeStop<<"共耗时:"<<timeStop-timeStart<<"ms"<<endl; timeStart = GetTickCount();
sqlite3_exec(db,"PRAGMA synchronous = OFF; ",,,);
sqlite3_exec(db,"begin;",,,);
for(int i = MAX_TEST_COUNT*; i < MAX_TEST_COUNT*; ++i)
{
stringstream ssm;
ssm<<"insert into SqliteTest values("<<i<<","<<i*<<","<<i/<<","<<i*i<<")";
sqlite3_exec(db,ssm.str().c_str(),,,);
}
sqlite3_exec(db,"commit;",,,);
timeStop = GetTickCount(); cout<< "事务+同步写关闭Insert"<<MAX_TEST_COUNT<<"条数据操作执行时间" << timeStart<<"结束时间:"<<timeStop<<"共耗时:"<<timeStop-timeStart<<"ms"<<endl; timeStart = GetTickCount();
//sqlite3_exec(db,"PRAGMA synchronous = FULL; ",0,0,0);
sqlite3_exec(db,"begin;",,,);
sqlite3_stmt *stmt;
const char* sql = "insert into SqliteTest values(?,?,?,?)";
sqlite3_prepare(db,sql,strlen(sql),&stmt,);
for(int i = MAX_TEST_COUNT*; i<MAX_TEST_COUNT*; ++i)
{
sqlite3_reset(stmt);
sqlite3_bind_int(stmt,,i);
sqlite3_bind_int(stmt,,i*);
sqlite3_bind_int(stmt,,i/);
sqlite3_bind_double(stmt,,i*i);
sqlite3_step(stmt);
}
sqlite3_finalize(stmt);
sqlite3_exec(db,"commit;",,,); timeStop = GetTickCount();
cout<< "事务+执行准备+同步写关闭Insert"<<MAX_TEST_COUNT<<"条数据操作执行时间:"<< timeStart<<"结束时间:"<<timeStop<<"共耗时:"<<timeStop-timeStart<<"ms"<<endl; }while(); cout<<"插入测试结束"<<endl;
Sleep();
sqlite3_close(db);
system("pause"); }

Sqlite3常用的插入方法及性能测试的更多相关文章

  1. DOM常用外部插入方法与区别

    1.DOM外部插入after()与before() 节点与节点之前有各种关系,除了父子,祖辈关系,还可以是兄弟关系.之前我们在处理节点插入的时候,接触到了内部插入的几个方法,这节我们开始讲外部插入的处 ...

  2. UIView的一些常用属性和方法

    UIView的一些常用属性和方法 1. UIView的属性 UIView继承自UIResponder,拥有touches方法. - (instancetype)initWithFrame:(CGRec ...

  3. (摘录)26个ASP.NET常用性能优化方法

    数据库访问性能优化 数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源. ASP.NET中提供了连接池(Co ...

  4. jQuery中常用的函数方法

    jQuery中常用的函数方法总结 Ajax处理 load(url,[data],[callback]) url (String) : 待装入 HTML 网页网址. data (Map) : (可选) ...

  5. jquery常用的一些方法

    一.选择网页元素(标签选择器) $(document) //选择整个文档对象 $('#myId') //选择ID为myId的网页元素 $('div.myClass') // 选择class为myCla ...

  6. 26个ASP.NET常用性能优化方法

    数据库访问性能优化 数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源. ASP.NET中提供了连接池(Co ...

  7. TensorFlow 常用函数与方法

    摘要:本文主要对tf的一些常用概念与方法进行描述. tf函数 TensorFlow 将图形定义转换成分布式执行的操作, 以充分利用可用的计算资源(如 CPU 或 GPU.一般你不需要显式指定使用 CP ...

  8. Egg中使用egg-mongoose和常用的Mongoose 方法

    Mongoose Mongoose就是一套操作MongoDB数据库的接口,而Egg中有对应的插件egg-mongoose. 安装 $ npm install egg-mongoose --save 配 ...

  9. 【终结版】C#常用函数和方法集汇总

    C#里面的常用的函数和方法非常重要,然而做题的时候会经常忘记这些封装好的方法,所以我总结一下 C#常用函数和方法集. [1]C#操作字符串的常用使用方法 在 C# 中,您可以使用字符数组来表示字符串, ...

随机推荐

  1. NginxWeb服务器安装

    1.   安装编译工具和库文件 [root@bigdata-51cdh opt]# yum -y install make zlib zlib-devel gcc-c++ libtool  opens ...

  2. Ubuntu下的解压缩

    一. 命令: .tar 解包:tar xvf FileName.tar打包:tar cvf FileName.tar DirName(注:tar是打包,不是压缩!)———————————————.gz ...

  3. dagride实现模糊查询

    一:首行放置搜索元素(可以是easyui中的input.datetimebox.combox等等) 将各个元素的value值获取到存为Json格式(data{a:..,b:..,c:..}),再回车或 ...

  4. 无法解决“Microsoft.SharePoint.Security, Version=15.0.0.0,”与“Microsoft.SharePoint.Security, Version=14.0.0.0”之间的冲突

    VisualStudio 2013创建控制台项目,.NetFramework选为4.5.生成目标平台:x64.然后添加对Microsoft.SharePoint.dll的引用. 生成项目时," ...

  5. 学习笔记 UpdateXml() MYSQL显错注入

    在学习之前,需要先了解 UpdateXml() . UPDATEXML (XML_document, XPath_string, new_value); 第一个参数:XML_document是Stri ...

  6. Java 策略模式和状态模式

    本文是转载的,转载地址:大白话解释Strategy模式和State模式的区别 先上图: 本质上讲,策略模式和状态模式做得是同一件事:去耦合.怎么去耦合?就是把干什么(语境类)和怎么干(策略接口)分开, ...

  7. Andriod 自定义控件之创建可以复用的组合控件

    前面已学习了一种自定义控件的实现,是Andriod 自定义控件之音频条,还没学习的同学可以学习下,学习了的同学也要去温习下,一定要自己完全的掌握了,再继续学习,贪多嚼不烂可不是好的学习方法,我们争取学 ...

  8. 【译】Spring 4 @PropertySource和@Value注解示例

    前言 译文链接:http://websystique.com/spring/spring-propertysource-value-annotations-example/ 本篇文章将展示如何通过@P ...

  9. json的理解及读取

    一: JSON 语法是 JavaScript 对象表示语法的子集,其语法规则如下: 数据在键值对中 数据由逗号分隔 花括号保存对象:{} 方括号保存数组:[] 如:[{"name" ...

  10. MySQL同步常见问题解答(自己的小心得)

    前几天刚刚注册了博客园,我想写一些技巧性的教程,今天给大家分享一个MySQL同步常见问题解答. Q:如果主服务器正在运行并且不想停止主服务器,怎样配置一个从服务器? A:有多种方法.如果你在某时间点做 ...