SQLite 性能优化实例分享_SQLite

来源:脚本之家  责任编辑:小易  

SQLite的数据库本质上来讲就是一个磁盘上的文件,所以一切的数据库操作其实都会转化为对文件的操作,而频繁的文件操作将会是一个很好时的过程,会极大地影响数据库存取的速度。例如:向数据库中插入100万条数据,在默认的情况下如果仅仅是执行sqlite3_exec(db,“insert into name values‘lxkxf',‘24';0,0,&zErrMsg);将会重复的打开关闭数据库文件100万次,所以速度当然会很慢。因此对于这种情况我们应该使用“事务”。具体方法如下:在执行SQL语句之前和SQL语句执行完毕之后加上rc=sqlite3_exec(db,"BEGIN;0,0,&zErrMsg);执行SQL语句rc=sqlite3_exec(db,"COMMIT;0,0,&zErrMsg);这样SQLite将把全部要执行的SQL语句先缓存在内存当中,然后等到COMMIT的时候一次性的写入数据库,这样数据库文件只被打开关闭了一次,效率自然大大的提高。有一组数据对比:测试1:1000 INSERTsCREATE TABLE t1(a INTEGER,b INTEGER,c VARCHAR(100));INSERT INTO t1 VALUES(1,13153,'thirteen thousand one hundred fifty three');INSERT INTO t1 VALUES(2,75560,'seventy five thousand five hundred sixty');995 lines omittedINSERT INTO t1 VALUES(998,66289,'sixty six thousand two hundred eighty nine');INSERT INTO t1 VALUES(999,24322,'twenty four thousand three hundred twenty two');INSERT INTO t1 VALUES(1000,94142,'ninety four thousand one hundred forty two');SQLite 2.7.6:13.061SQLite 2.7.6(nosync):0.223测试2:使用事务 25000 INSERTsBEGIN;CREATE TABLE t2(a INTEGER,b INTEGER,c VARCHAR(100));INSERT INTO t2 VALUES(1,59672,'fifty nine thousand six hundred seventy two');24997 lines omittedINSERT INTO t2 VALUES(24999,89569,'eighty nine thousand five hundred sixty nine');INSERT INTO t2 VALUES(25000,94666,'ninety four thousand six hundred sixty six');COMMIT;SQLite 2.7.6:0.914SQLite 2.7.6(nosync):0.757www.zgxue.com防采集请勿采集本网。

最早接触 iOS 开发了解到的第一个缓存数据库就是 SQLite,后面一直也以 SQLite 作为中坚力量使用,以前没有接触到比较大量数据的读写,所以在性能优化方面关注不多,这次对一个特定场景的较多数据批量读写做了一个性能优化,使性能提高了十倍。

本文主要讨论在Android应用如何优化SQLite的性能和资源占用。1,使用事务(Transaction)在默认情况下每一个SQL语句都被包一个全新的事务内,比如执行一个如INSERT这样基本的数据库操作,就会放到一个新创建

大致应用场景是这样:

可以再增加一列name_tmp,存储name的反串,比如存储的是 cbaxxxx值,跟name字段反着,然后在name_tmp字段建立索引,这样查询的时候可以使用select*from tablename where name_tmp like 'abc%';

每次程序启动会从服务器拉取一些数据,对本地数据库两个表进行同步更新,不存在就写入,存在就更新其字段。数据少的时候几十条,多的上千条。

在数据库的sql语句前加:\"begin;result=sqlite3_exec(_db,sql.c_str(),nullptr,nullptr,&errMsg);if(result!SQLITE_OK){ log(\"insert error,code=d,message=s\\n\",result,errMsg);} }

由于缓存的数据可能会存在异步同时读写,所以做了一个后台同步队列,所有的缓存数据库操作都在这个队列里面,然后我监控了一下写数据库的关键代码执行耗时,一千条数据更新到数据库就能耗时 30 秒之久,磁盘写入在 1.5M/s 浮动, 虽然没有卡主线程,这个消耗即使在后台也是不可容忍的。

使用事务,使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction()方法时会检查事务的标志是否为成功,如果为成功则提交事务,否则回滚事务。当应用需要提交事务,必须

核心的数据库操作大概是这样的

like 是模糊查询,通配符%表示任意字符,like‘%5400%’这个条件要进行全表扫描,而 YY_BH LIKE’X5400%’只需要索引出开头为X5400就可以,效率当然就可以提高了

for 1000 : {Select -> Update Or InsertSelect -> Update Or Insert}

由于牵涉到两张表,所以会有两次,经过测试,Select 一次几乎没有多少消息,可是 Update 或者 Insert ( [FMDatabaseQueue executeUpdate:] ) 就消耗大了,因为会写入磁盘,然后想到是不是可以把所有的 SQL 语句拼接起来,最后只想一次;再后来想到 SQLite 不是有事务 ( Transaction ) 嘛,于是尝试了一下利用 FMDB 的事务操作,在循环开始前 [db beginTransaction] ,循环结束 [db commit],包起来就行了。

增加事务之后的大概逻辑:

beginTransactionfor 1000 : {Select -> Update Or InsertSelect -> Update Or Insert}commit

测试效果非常好,整个耗时从 30 秒下降到了2.8 秒左右,仅仅增加了两行代码。

总结:

踩过的坑,走过的坎,都是以后的经验

虽然利用事务取巧来提高了性能,但是这样做其实并不安全,好在所属场景对这部分数据绝对一致要求不是太高。

模拟器和真机有时候测试并不能重现同一个问题,因为所属架构、CPU、硬盘都不一样,所以性能测试最好还是以真机为准。该问题测试的时候在模拟器上很多问题都没有,因为硬盘比真机读写速度要高,所以避免了很多问题,测试的时候也就没有发现。

数据库设计设计的时候得多考虑考虑,多想想以后怎么扩展,怎么升级,读写的时候性能怎么样

第1条语句,跟create_time索引没关系第2条语句,应该不会使用create_time索引,因为即便用了索引最后还是要读表数据,还不如直接全表读数据然后在内存中排序快第3条语句,不知道0到1383525367的create_time选出的记录数相对于全表记录数的比率有多大,太多了应该也不会使用索引,因为最后还是要读一遍表数据,如果比率比较小应该会用上索引内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • sqlite优化方法
  • android创建数据库(sqlite)保存图片示例
  • sqlite3中的日期时间函数使用小结
  • sqlite3中自增主键相关知识总结
  • c#操作sqlite方法实例详解
  • python之sqlalchemy创建表的实例详解
  • sqlite 内存数据库学习手册
  • sqlite学习手册(sqlite在线备份)
  • 基于sqlite特殊字符转义的实现方法
  • 保护你的sqlite数据库(sqlite数据库安全秘籍)
  • 初识sqlite3数据库
  • sqlite教程(三):数据表和视图简介
  • sqlite教程(十三):c语言编程实例代码(1)
  • sqlite时间戳转时间语句(时间转时间戳)
  • sqlite3 api 编程手册
  • 求sqlite数据库索引创建语句或性能优化方案
  • sqlite如何优化
  • sqlite大数据库怎样进行性能优化
  • 如何优化sqlite的查询速度
  • 如何优化SQLite-Android开发实例
  • 请教一个SQLITE like语句优化问题
  • 如果使用sqlite,大批量的插入数据,需要做哪些优化
  • 如何提升SQLite的性能
  • 请教一个SQLITE like语句优化问题
  • 如何创建sqlite数据库
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全mssqlmysqlmariadboracledb2mssql2008mssql2005sqlitepostgresqlmongodbredisaccess数据库文摘数据库其它首页sqlitesqlite优化方法android创建数据库(sqlite)保存图片示例sqlite3中的日期时间函数使用小结sqlite3中自增主键相关知识总结c#操作sqlite方法实例详解python之sqlalchemy创建表的实例详解sqlite 内存数据库学习手册sqlite学习手册(sqlite在线备份)基于sqlite特殊字符转义的实现方法保护你的sqlite数据库(sqlite数据库安全秘籍)初识sqlite3数据库sqlite教程(三):数据表和视图简介sqlite教程(十三):c语言编程实例代码(1)sqlite时间戳转时间语句(时间转时间戳)sqlite3 api 编程手册sqlite中文乱码问题原因分析及解sqlite3中的日期时间函数使用小结sqlite3 top的查询及limit语法介linux sqlite3 基本命令sqlite 错误码整理sqlite3中自增主键相关知识总结sqlite优化方法sqlite循环批量插入数据采用批处sqlite3 使用总结sqlite 常用函数 推荐sqlite 性能优化实例分享sqlite教程(五):数据库和事务sqlite 入门教程二 sqlite的创建、修改、sqlite字符串比较时的大小写问题解决方法sqlite优化方法sqlite循环批量插入数据采用批处理文件实初识sqlite3数据库sqlite教程(五):索引和数据分析/清理sqlite学习手册(sqlite在线备份)sqlite 入门教程四 增删改查 有讲究
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved