本人翻译, 原文见:

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, 我想我下一步得优化插入操作了.

  1. String sql = "INSERT INTO table (number, nick) VALUES (?, ?)";
  2. SQLiteStatement stmt = db.compileStatement(sql);
  3. for (int i = 0; i < values.size(); i++) {
  4. stmt.bindString(1, values.get(i).number);
  5. stmt.bindString(2, values.get(i).nick);
  6. stmt.execute();
  7. stmt.clearBindings();
  8. }

有了上面的改动后, 我在模拟器上测试, 时间从71秒减少到56秒, 但是在真机上测的时候, 时间反而多了几秒, 我反复测了几次, 还是差不多一样的结果.

进一步研究, 我从SQLite的一个文档页面看到“PRAGMA synchronous = OFF” 将会告诉SQLite, 当它把数据传入操作系统的时候, 不要立即同步. 这个设置让插入时间从71秒减少的50秒, 在真机上的结果是361秒, 差不多快2分钟.

感觉到找到路子之后, 我认为是文件系统减慢了插入操作, 我在网上找到了很多关于Galaxy S I/O 性能问题的参考 - 所有的都与RFS文件系统相关. 对于SQLite而言, 它每插入一次数据, 都会执行一下fsync, 以保证数据写入了磁盘. 再看SQLite文档, 我发现用transactions能够将数据保存在内存中, 只有在commit时候才写入文件系统. 因此我改动如下:

  1. String sql = "INSERT INTO table (number, nick) VALUES (?, ?)";
  2. db.beginTransaction();
  3. SQLiteStatement stmt = db.compileStatement(sql);
  4. for (int i = 0; i < values.size(); i++) {
  5. stmt.bindString(1, values.get(i).number);
  6. stmt.bindString(2, values.get(i).nick);
  7. stmt.execute();
  8. stmt.clearBindings();
  9. }
  10. db.setTransactionSuccessful();
  11. db.endTransaction();

结合transactions和 compiled statements后, 性能有了巨大的提升: 从71秒到不可置信的5秒! 在Galaxy上的结果更是牛逼: 从478秒到1.5秒!

结论:

- 除非你只执行单次的insert, 或者你需要数据立即写入文件系统, 不然的话就用transactions

- 保证你的程序在真机上测试过, 最好是多台机器上测.

- 我上面的性能提升只在Samsung Galaxy S上测过, 不同的机器可能还是会有性能问题.

SQLite 批量insert - 如何加速SQLite的插入操作的更多相关文章

  1. 【转】insert忽略重复、mysql插入操作跳过、插入覆盖覆盖、mysql更新重复

    需求背景:一般情况,插入数据的时候,有脏数据的情况,主键重复的话,直接insert into 会报错的,然后下面的sql都不再执行了,如果可以确定后面的数据可以覆盖前面的数据,直接用replace i ...

  2. Qt SQLite 批量插入优化(SQLite默认将每条语句看成单独的事务)good

    使用SQLite存储数据时发现插入速度太慢,程序跑了将近五分钟才插入了不到三千条.上网查资料才发现,SQLite这种文件数据库与MySql机制不一样,每条事务都有打开和关闭文件的步骤,SQLite默认 ...

  3. (C#版本)提升SQlite数据库效率——开启事务,极速插入数据,3秒100万,32秒1000万条数据

    SQLite插入数据效率最快的方式就是:开启事务  +   insert语句  +  关闭事务(提交) 利用事务的互斥性,如果在批量的插入操作前显式地开启一次事务,在插入操作结束后,提交事务,那么所有 ...

  4. sqlite批量处理数据性能优化

    最近设计到sqlite数据库批量操作的,性能很是问题.于是一番研究(站在巨人肩膀)从网上整理出来相关性能优化方向.大体分三个级别,一般第一个阶段已足够. 1.sqlite每次插入数据(每调用一次sql ...

  5. csv文件批量导入数据到sqlite。

    csv文件批量导入数据到sqlite. 代码: f = web.input(bs_switch = {})  # bs_switch 为from表单file字段的namedata =[i.split( ...

  6. android之SQLite数据库insert操作

    原型: long Android.database.sqlite.SQLiteDatabase.insert(String table, String nullColumnHack, ContentV ...

  7. Sqlite执行insert or ignore 或insert or replace语句。

    Sqlite执行insert or ignore 或insert or replace语句. ,); ,); 上面的第一条语句是每次执行时,如果不存在,则添加,如果存在,则更新. 上面的第二条语句是每 ...

  8. andorid SQLite数据库的增删改查 和事务操作

    .xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android ...

  9. JDBC批量Insert深度优化(有事务)

    环境: MySQL 5.1 RedHat Linux AS 5 JavaSE 1.5 DbConnectionBroker 微型数据库连接池   测试的方案: 执行10万次Insert语句,使用不同方 ...

随机推荐

  1. andorid 练习之黑名单

    activity_mian.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout ...

  2. What he did

    //记录组内成员具体完成工作情况,格式为:时间-事件-人物 2015-4-19 用户需求分析---主要由韩林编写,国旗,李春伟辅助编写,国旗发布文档至博客 2015-4-22 快速原型---由郭龙东完 ...

  3. linux下实时查看tomcat运行日志

    查看实时日志: tail -f catalina.out Ctrl+c 是退出tail命令

  4. Eclipse中出现-访问限制由于对必需的库XX具有一定限制,因此无法访问类型

    在项目上点击右键,找到构建路径.然后选择配置配置路径.按如下步骤来配置: 1 点击库选项 2把系统库扩展开来 3点击访问规则 4点击右边的添加按钮 5添加访问规则 6 分辨率设为可访问 7规则模式设为 ...

  5. Quartz任务调度快速入门(转)

    转自http://www.blogjava.net/baoyaer/articles/155645.html 概述 了解Quartz体系结构 Quartz对任务调度的领域问题进行了高度的抽象,提出了调 ...

  6. Windows Phone 8.1商店启动协议

    最近开发wp8.1已经两个月了,感觉坑不少,原来8时代的商店api多明了,微软不给封装就算了,至少你要在msdn上明显的地方标注下啊...................顺便在吐槽下bing,找了一个 ...

  7. Android 网络开发免费API接口

    http://www.juhe.cn/                              聚合数据              目前很多接口都收费 https://www.showapi.com ...

  8. 准备找工作第三天——java基础_由有道云笔记倒入

    循环:跳出多重循环:通过设置标号: 1    ok: 2    for(int i=0;i<10;i++) 3    { 4    for(int j=0;j<10;j++) 5    { ...

  9. bzoj 1064

    题意:戳这里 思路:很明显是一个图论模型.. 就两种图形: 1.图中存在环,那么就是所有环的gcd为最大答案.gcd的大于3的最小约数为最小答案 2.不存在环,那么是每个弱连通块的最长链之和为最大答案 ...

  10. C++类库介绍

    如果你有一定的C基础可能学起来比较容易些,但是学习C++的过程中又要尽量避免去使用一些C中的思想:平时还要多看一些高手写的代码,遇到问题多多思考,怎样才能把问题抽象化,以使自己头脑中有类的概念:最后别 ...