本人翻译, 原文见:

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. VB6.0和VB.Net的函数等对照表

    VB6.0和VB.Net的对照表 VB6.0 VB.NET AddItem Object名.AddItem Object名.Items.Add ListBox1.Items.Add ComboBox1 ...

  2. JS实现隔行变色,鼠标移入高亮

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 31.0px Consolas; color: #2b7ec3 } p.p2 { margin: 0.0px ...

  3. .net 泛型运用

    DAL层 private DbContext MyContext; public BaseRepository(DbContext context) { MyContext = context; } ...

  4. Linux部署apache

    一.我们使用源码安装 官网:https://httpd.apache.org/文档:https://httpd.apache.org/docs/2.4/ 下载源码包 httpd-2.4.20.tar. ...

  5. JavaScript-setTimeout

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  6. [译]GLUT教程 - glutPostRedisplay函数

    Lighthouse3d.com >> GLUT Tutorial >> Avoiding the Idle Func >> glutPostRedisplay 直 ...

  7. 添加ModelGoon插件Eclipse自动生成UML图

    下载ModelGoonjar包 http://download.csdn.net/detail/u011070297/8366021 下载完该jar之后,直接拷贝到Eclipse安装目录下的dropi ...

  8. linux系统基础网络配置

    1.修改主机名 临时方法: 退出当前shell重新登录即可生效.此法只能临时修改生效.重启系统后失效. 提示:很多人使用hostname主机名来修改,其实这个只是作为暂时的.重启后将恢复到配置前的主机 ...

  9. SQL中的取整函数FLOOR、ROUND、CEIL、TRUNC、SIGN

    1 trunc(value,precision)按精度(precision)截取某个数字,不进行舍入操作.2 round(value,precision)根据给定的精度(precision)输入数值. ...

  10. WPF快速入门系列(6)——WPF资源和样式

    一.引言 WPF资源系统可以用来保存一些公有对象和样式,从而实现重用这些对象和样式的作用.而WPF样式是重用元素的格式的重要手段,可以理解样式就如CSS一样,尽管我们可以在每个控件中定义格式,但是如果 ...