本人翻译, 原文见:sql
http://tech.vg.no/2011/04/04/speeding-up-sqlite-insert-operations/数据库
我正在开发一个Android程序, 它使用SQLite存储大约6000行的数据, 这些数据会按期从网上更新. 在模拟器上, 从网络获取和解析CSV格式的数据所花的时间大概是20秒, 可是把数据插入的数据库的时间是71秒.网络
由于数据更新的操做差很少一个星期才有一次, 所以我认为1分多钟的操做时间是能够接受的. 但当我把程序在真机上跑的时候, 6000行的插入时间让我吓了一跳 -- 478秒, 差很少8分钟. 很奇怪, 通常来讲, 真机要比模拟器快, 况且我用的是Sanmsung Galaxy S - 当时最快的Android设备之一. 这是我第一次使用SQLite, 我想我下一步得优化插入操做了.性能
有了上面的改动后, 我在模拟器上测试, 时间从71秒减小到56秒, 可是在真机上测的时候, 时间反而多了几秒, 我反复测了几回, 仍是差很少同样的结果.测试
进一步研究, 我从SQLite的一个文档页面看到“PRAGMA synchronous = OFF” 将会告诉SQLite, 当它把数据传入操做系统的时候, 不要当即同步. 这个设置让插入时间从71秒减小的50秒, 在真机上的结果是361秒, 差很少快2分钟.优化
感受到找到路子以后, 我认为是文件系统减慢了插入操做, 我在网上找到了不少关于Galaxy S I/O 性能问题的参考 - 全部的都与RFS文件系统相关. 对于SQLite而言, 它每插入一次数据, 都会执行一下fsync, 以保证数据写入了磁盘. 再看SQLite文档, 我发现用transactions可以将数据保存在内存中, 只有在commit时候才写入文件系统. 所以我改动以下:spa
结合transactions和 compiled statements后, 性能有了巨大的提高: 从71秒到不可置信的5秒! 在Galaxy上的结果更是牛逼: 从478秒到1.5秒!操作系统
结论:翻译
- 除非你只执行单次的insert, 或者你须要数据当即写入文件系统, 否则的话就用transactionssqlite
- 保证你的程序在真机上测试过, 最好是多台机器上测.
- 我上面的性能提高只在Samsung Galaxy S上测过, 不一样的机器可能仍是会有性能问题.