关于sqlite的事务的使用
缘起
sqlite写入500条不大的记录居然要花费20多秒的时间,太慢了!!!
分析
sqlite是一个非常优秀的嵌入式数据库,读取性能非常好,写入性能就比较差一些,为什么写入性能差呢?下面做了一个测试。
下面是对500+条记录些操作的系统调用的观察,发现时间基本花费在了fdatasync系统调用上,调用2064次;write系统调用虽然8049次,但是write并不保证逻辑,所以速度很快。
$ strace -c php test.php 27.688107013702 (耗时27.6s) % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 88.73 0.073919 36 2064 fdatasync 3.88 0.003231 0 8049 write 3.77 0.003144 6 516 unlink 1.12 0.000929 0 6730 fcntl64 0.90 0.000751 0 9118 3 _llseek 0.86 0.000720 1 1218 82 open 0.24 0.000198 0 1143 close 0.20 0.000167 0 1182 read 0.16 0.000131 0 520 518 access 0.05 0.000039 1 42 1 lstat64 0.04 0.000033 0 194 mmap2 0.03 0.000027 0 92 munmap 0.03 0.000021 0 58 49 stat64 0.00 0.000000 0 1 execve 0.00 0.000000 0 20 time 0.00 0.000000 0 21 brk 0.00 0.000000 0 3 2 ioctl 0.00 0.000000 0 3 gettimeofday 0.00 0.000000 0 1 readlink 0.00 0.000000 0 2 uname 0.00 0.000000 0 28 mprotect 0.00 0.000000 0 4 poll 0.00 0.000000 0 5 rt_sigaction 0.00 0.000000 0 2 rt_sigprocmask 0.00 0.000000 0 2 getcwd 0.00 0.000000 0 1 getrlimit 0.00 0.000000 0 648 fstat64 0.00 0.000000 0 4 futex 0.00 0.000000 0 1 sched_setaffinity 0.00 0.000000 0 2 sched_getaffinity 0.00 0.000000 0 1 set_thread_area 0.00 0.000000 0 1 set_tid_address 0.00 0.000000 0 1 set_robust_list 0.00 0.000000 0 4 socket 0.00 0.000000 0 4 2 connect 0.00 0.000000 0 1 send 0.00 0.000000 0 1 recvfrom 0.00 0.000000 0 1 shutdown 0.00 0.000000 0 5 setsockopt ------ ----------- ----------- --------- --------- ---------------- 100.00 0.083310 31693 657 total
查资料
http://www.cnblogs.com/KimSky/archive/2011/05/31/2064028.html
发现: 如果使用事务的方式批量插入数据,效果会有明显改善,因为默认情况下每次写入操作都会落地才返回的(更加安全靠谱),如果使用事务,则批量数据一次性落地。
修改代码,分析系统调用如下:(发现fdatasync调用12次)
$ strace -c php test.php 0.20949816703796 (耗时 209ms) % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 71.64 0.000998 83 12 fdatasync 7.61 0.000106 1 155 read 5.24 0.000073 0 194 mmap2 4.16 0.000058 0 195 write 2.58 0.000036 0 135 fstat64 1.65 0.000023 0 92 munmap 1.58 0.000022 1 28 mprotect 1.51 0.000021 1 42 1 lstat64 1.44 0.000020 20 1 readlink 1.29 0.000018 0 238 3 _llseek 1.29 0.000018 0 58 49 stat64 0.00 0.000000 0 192 82 open 0.00 0.000000 0 117 close 0.00 0.000000 0 3 unlink 0.00 0.000000 0 1 execve 0.00 0.000000 0 20 time 0.00 0.000000 0 7 5 access 0.00 0.000000 0 21 brk 0.00 0.000000 0 3 2 ioctl 0.00 0.000000 0 3 gettimeofday 0.00 0.000000 0 2 uname 0.00 0.000000 0 4 poll 0.00 0.000000 0 5 rt_sigaction 0.00 0.000000 0 2 rt_sigprocmask 0.00 0.000000 0 2 getcwd 0.00 0.000000 0 1 getrlimit 0.00 0.000000 0 61 fcntl64 0.00 0.000000 0 4 futex 0.00 0.000000 0 1 sched_setaffinity 0.00 0.000000 0 2 sched_getaffinity 0.00 0.000000 0 1 set_thread_area 0.00 0.000000 0 1 set_tid_address 0.00 0.000000 0 1 set_robust_list 0.00 0.000000 0 4 socket 0.00 0.000000 0 4 2 connect 0.00 0.000000 0 1 send 0.00 0.000000 0 1 recvfrom 0.00 0.000000 0 1 shutdown 0.00 0.000000 0 5 setsockopt ------ ----------- ----------- --------- --------- ---------------- 100.00 0.001393 1620 144 total
结论:
1. 借用事务采用批量写入的方式来加速写操作
2. 如果业务上不能批量操作呢?似乎有一个nosync的sqlite版本(不知道为什么不是一个配置选项)
参考资料: http://www.sqlite.org/speed.html
3. 如果数据量太大,可以分多批提交事务,因为事务是需要内存的。(不过,sqlite一般不会存放N个G的数据的,几百MB已经算是比较大的了,这样的数据量内存还是吃的消的)
参考资料:
http://www.phpchina.com/archives/view-33876-1.html
关于sqlite的系列分析文章(可以看看)
http://www.cnblogs.com/hustcat/archive/2009/02/12/1389448.html
SQLite的原子提交原理
http://www.cnblogs.com/vagerent/archive/2008/11/05/1327247.html
建议继续学习:
- 分布式系统的事务处理 (阅读:6011)
- 在perl中连接和使用sqlite做数据存储 (阅读:5067)
- 从Mysql到Sqlite的迁移 (阅读:4199)
- 分布式事务性能分析 (阅读:3863)
- MySQL数据库分布式事务XA优缺点与改进方案 (阅读:3575)
- SQLIte这么娇小可爱,不多了解点都不行啊 (阅读:3521)
- Google Megastore系统事务机制 (阅读:2379)
- 使用python将Sqlite中的数据直接输出为CVS (阅读:2326)
- MySQL数据库分布式事务XA的实现原理分析 (阅读:2294)
- Storm入门教程 第五章 一致性事务 (阅读:1929)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:phpor 来源: PHPor 的Blog
- 标签: sqlite 事务
- 发布时间:2013-09-23 13:54:28
- [44] 界面设计速成
- [40] 视觉调整-设计师 vs. 逻辑
- [39] Oracle MTS模式下 进程地址与会话信
- [35] 如何拿下简短的域名
- [35] 程序员技术练级攻略
- [35] IOS安全–浅谈关于IOS加固的几种方法
- [33] 图书馆的世界纪录
- [33] android 开发入门
- [32] 【社会化设计】自我(self)部分――欢迎区
- [30] 读书笔记-壹百度:百度十年千倍的29条法则