序:

性能优化新手必读、老手可鉴、高手可略:

     性能优化的坑:不管是新手还是老手,做过性能优化的小伙伴应该都掉过这样的坑,有时太相信自己的直觉,没有做过性能剖析,没有分析报告,就开始优化代码,结果鼓捣了半天,怎么还是这么慢呢?还整出了俩个bug,只能呵呵,然后,说多都是泪啊。。。。

     如果你现在正在做性能优化工作,但是还没做性能剖析,并不确定sqlite的操作就是程序的性能瓶颈点,请不要掉坑了。

可略:

     使用sqlite,几乎都会面临多线程、多进程并发访问、读写数据性能问题。并发访问可参考 http://linzimo777.blog.51cto.com/5334766/1544202,今天分享一下sqlite的性能优化。

      很多小伙伴吐槽 sqlite 很戳,我也曾经跟项目架构师交流并吐槽sqlite,架构师说,“sqlite 虽然有不足,但是却为我们省去了很多工作”。仔细想想,很有道理。之前另一个项目组的小伙伴做ios端开发,使用 xml存储元数据,导致工作繁琐,实现复杂,后续改用sqlite,简单了很多。

     经过一年多项目从雏形到趋于稳定,遇到并解决sqlite各方面的问题。大家吐槽的无非是 sqlite 对并发的支持、读写性能不够、功能支持不全。 sqlite 对并发和性能的支持还是不错,只是需要配置和做处理,其实都不复杂。sqlite内部使用大粒度文件锁,其实就是基于对性能的考虑,避免竞争,把控制交给外层。

      

进入正题:

一:优化 sqlite 写性能

<1>:批量更新数据的场景,使用数据库事务,批量更新数据是非常快的。


<2>:单条更新数据的场景,sqlite 有两种实现事务的模式  rollback journal 和 wal(3.7.0版本开始支持)。关于这两种模式的介绍,我就不再充当拷贝机了,

请参考:

http://www.sqlite.org/draft/wal.html(sqlite官网的介绍)

http://blog.csdn.net/dyllove98/article/details/8841973(不想看英文的话,这个也介绍得比较清楚)

总结一下原理:简单说 rollback journal 原子更新数据到数据库,wal 是定期批量更新数据到数据库。

补充的是:wal 模式下要更进一步提升性能的话,可以考虑改变 checkpoint。我们在把  checkpoint 改成了10000(默认是1000),checkpoint = 1000 是 日志文件 1M 的时候回写到数据库,改成 10000 就变成了 日志文件 10M 时回写数据到数据库。 demo测试性能,有2倍+的提升。


<3>:数据安全性不高的场景,可以考虑更改 syncchronous = off 的模式;(写数据的速度50倍+的提升)

     数据安全性较高的场景,可以考虑更改 syncchronous = nomal 的模式;(写数据的性能也有5倍+的提升)

注意:sqlite 默认是 syncchronous = full。


关于同步模式的介绍,同样的我就不再充当拷贝机。

参考:

http://www.sqlite.org/pragma.html(sqlite官网介绍)

http://blog.csdn.net/qinlicang/article/details/6079453(其实这个是对上面官网部分参数介绍的中文翻译)

ps:有人会觉得  nomal  模式下数据安全性不够,当初我也有这样顾虑,就写了demo模式多次模拟测试了程序崩溃等场景,没有发现 nomal 模式下数据丢失的情况,后续就在项目中日志记录使用的 off 模式,元数据记录使用了 nomal 模式。到现在已经几个月了(我们的产品已发布,已有大量的用户每天都在使用),使用off 模式和使用 nomal 模式都没有发现数据丢失、数据库损坏的情况。官网的描述也是,如果 nomal 模式下数据库损坏了,那么你的硬盘也很可能坏了。


 <4>:更改sqlite的各种参数提升性能。关于参数的介绍,参看<3>中的两个链接资料。

ps:在我的 demo 性能测试中,更改 cache_size = 8000 会有一定的性能提升。更改其他参数没有明显提升。

二:查询性能

<1> 建立索引

参考:

http://www.cnblogs.com/stephen-liu74/archive/2012/02/17/2322335.html

索引的原理什么的,就不多介绍了,这是数据库的基本知识。

参考:google 。


<2> 根据具体的使用场景,进行分表、分库

参考:google


环境:win7 64位系统

程序语言:c++

4核cpu,4G内存

sqlite version:3.8.2


当然各个环境不同,结果会有差异,仅供参考。

最好是写 demo 进行测试,得到测试报告以后,根据实际场景需要,进行性能优化。


总结:作为轻量级数据库 sqlite 是很好的,需要我们根据不同的场景进行设置。


如果上面的方法还没有解决你的性能问题。。。。。

呵呵,说明架构师在框架技术选型时考虑不足,换数据库吧。看看什么 leveldb 这种 kv 数据库是否满足你的需求。


后续还会在分享一下,sqlite加密、那些年,使用sqlite踩过的天坑。欢迎有兴趣的小伙伴关注!


因个人水平有限,如有笔误、讲解不清楚、探究的不清楚的地方。还请各位路过的小伙伴们海涵,并指出问题,帮助我干掉它。转载请注明出处。