序:
性能优化新手必读、老手可鉴、高手可略:
性能优化的坑:不管是新手还是老手,做过性能优化的小伙伴应该都掉过这样的坑,有时太相信自己的直觉,没有做过性能剖析,没有分析报告,就开始优化代码,结果鼓捣了半天,怎么还是这么慢呢?还整出了俩个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踩过的天坑。欢迎有兴趣的小伙伴关注!
http://blog.51cto.com/linzimo777/1546802