最近做到的项目涉及一个大数据量缓存重传,其中要用到的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. PhpStorm集成xdebug进行断点调试

    本文介绍如何使用PhpStorm集成xdebug在本地开发环境进行断点调试的技巧. 我配置的环境是:Windows10 + PhpStorm10.0.1 + PHP5.6. 1. 下载xdebug的扩 ...

  2. 后缀数组(suffix array)详解

    写在前面 在字符串处理当中,后缀树和后缀数组都是非常有力的工具. 其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料. 其实后缀数组是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现, ...

  3. Redis简单案例(四) Session的管理

    负载均衡,这应该是一个永恒的话题,也是一个十分重要的话题.毕竟当网站成长到一定程度,访问量自然也是会跟着增长,这个时候, 一般都会对其进行负载均衡等相应的调整.现如今最常见的应该就是使用Nginx来进 ...

  4. 设计模式(十一)外观模式(Facade Pattern)

    一.引言 在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化,然而为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 ...

  5. php:ci学习笔记1

    ci下载的开发包:     phpstudy的部署: phpstudy的根目录是:D:\WWW 新建目录 cms  把ci开发包的application   system index.php  lic ...

  6. 织梦cms常用标签

    dedecms简介:织梦内容管理系统(DedeCms) 以简单.实用.开源而闻名,是国内知名的PHP开源网站管理系统,也是使用用户较多的PHP类CMS系统,在经历多年的发展,目前的版本无论在功能,还是 ...

  7. ORACLE实现自定义序列号生成

    实际工作中,难免会遇到序列号生成问题,下面就是一个简单的序列号生成函数 (1)创建自定义序列号配置表如下: --自定义序列 create table S_AUTOCODE ( pk1 ) primar ...

  8. logstash+elasticsearch+kibana管理日志(安装)

    logstash1.先安装jdk2.wget https://download.elastic.co/logstash/logstash/logstash-2.4.0.tar.gz tar -xzvf ...

  9. MySQL大数据优化

    我们考虑的情况是在你的数据量很大的情况下,千万级别的数据量.不要当我们的请求响应时间已经让我无法忍受的时候,再来想起来优化,可能有点迟了.因为可能会丢失很多潜在的价值客户.所以,在我们当初设计表,或者 ...

  10. VBA 格式化字符串 - Format大全

    VBA 格式化字符串 VBA 的 Format 函数与工作表函数 TEXT 用法基本相同,但功能更加强大,许多格式只能用于VBA 的 Format 函数,而不能用于工作表函数 TEXT ,以下是本人归 ...