`

SQLite 批量insert - 如何加速SQLite的插入操作

 
阅读更多

本人翻译, 原文见:

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

 

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

 

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

 

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

 

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

 

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

 

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

 

结论:

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

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

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

 

0
0
分享到:
评论
1 楼 shiylqq 2014-05-07  
启发很大,谢谢啦!

相关推荐

    sqlite-tools-linux-x86-3350400.zip

    7. **.sql** 文件:可能包含预定义的SQL脚本,用于创建数据库结构、初始化数据或者执行批量数据操作。 这些工具在Linux x86平台上运行,这意味着它们适用于32位Linux操作系统。版本号“3350400”表示这是SQLite的一...

    c# 对sqlite基本操作,带批量插入(百万级秒插)

    在本文中,我们将深入探讨如何使用C#进行SQLite的基本操作,特别是关注批量插入功能,这在处理大量数据时尤其有用,如标题所述,可以实现百万级数据的秒级插入。SQLite是一个轻量级的数据库引擎,它允许在无需服务器...

    C语言实现SQLite的批量插入及性能对比

    本话题聚焦于C语言如何实现SQLite的批量插入以及性能对比,这对于优化数据库操作效率具有深远意义。 首先,让我们详细探讨SQLite的单个插入与批量插入。在C语言中,SQLite提供了SQL接口,通过API函数来执行SQL语句...

    SQLite数据库-批量数据快速入库方法总结-lt

    相对而言,批量数据循环绑定插入方式通过使用预编译接口sqlite3_prepare_v2一次解析参数化SQL语句,并通过循环绑定sqlite3_bind以及执行sqlite3_step来提高效率,这种方式中SQL语句仅被解析一次,后续操作均复用第一...

    Python库 | sqlite_utils-1.2.2-py3-none-any.whl

    sqlite_utils还提供了批量插入、更新和删除数据的功能,大大提高了处理大量数据的效率。 总结,sqlite_utils库为Python开发者提供了一个高效的SQLite数据库操作接口,它的易用性和灵活性使得在处理小型数据库时无需...

    JavaScript sqlite3 大数据量插入

    Node.js结合sqlite3模块实现Sqlite数据库建表并实现大数据量的快速插入

    android sqlite 批量插入数据优化代码

    "android sqlite 批量插入数据优化代码"这个主题正是针对这一需求,探讨如何高效地在SQLite数据库中进行大量数据的插入操作。 首先,我们要理解SQLite的基本插入语句,通常是这样的: ```sql INSERT INTO 表名 (列...

    PyPI 官网下载 | sqlite-generate-1.0.tar.gz

    3. **插入数据**:使用`cursor.execute()`方法执行`INSERT`语句将数据写入表中。 4. **查询数据**:利用`SELECT`语句获取数据库中的数据,可以使用`fetchone()`, `fetchall()`等方法获取结果。 5. **更新与删除数据*...

    sqlite避免重复插入数据

    根据提供的文件信息,本文将详细解析如何在SQLite数据库中避免重复数据插入的问题,并结合实际应用场景进行探讨。 ### SQLite 数据库避免重复数据插入 在数据库管理中,确保数据的唯一性是非常重要的,特别是在...

    Sqlite数据库里插入数据的条数上限是500

    今天在向Sqlite数据库里插入数据的时候,报了这样一个错: 代码如下: “too many terms in compound SELECT” 去Stackoverflow上查了一下,发现有人回答这个问题:链接 原来一次性向数据库里插入数据的条数不能太...

    Python库 | fastqc_sqlite-0.3-py2.py3-none-any.whl

    4. **性能优化**:可能包含对大量数据处理的优化,例如批量插入和索引构建,以提高处理速度。 在使用这个库之前,确保你的环境已经安装了Python和`pip`。然后,你可以通过命令行执行`pip install fastqc_sqlite-0.3...

    Python库 | sqlite_generate-0.1-py3-none-any.whl

    3. **数据操作**:包括插入(`INSERT`)、更新(`UPDATE`)、删除(`DELETE`)和查询(`SELECT`)等操作。`sqlite_generate`可能提供了一些高级接口,简化了这些操作。 4. **事务处理**:数据库操作通常涉及事务,...

    android中SQLite数据库中用insert同时插入多条记录的方法和效率比较

    Android 中 SQLite 数据库中用 insert 同时插入多条记录的方法和效率比较 在 Android 开发中,我们常会遇到这样一种情况:在建立一个 SQLite 数据库时,想同时插入大量数据。那么应该怎么做呢?下面我们将比较三种...

    SQLLITE的批量插入。。。

    本话题主要聚焦于SQLite的批量插入操作,这是一种提高数据导入效率的重要技术。 批量插入在处理大量数据时尤其有用,它可以显著减少与数据库交互的次数,从而降低系统资源的消耗并提升性能。在SQLite中,我们可以...

    sqlite3性能优化源代码 数据插入 开启事务 执行准备 性能提升 每秒百万条数据写入

    批量插入数据时,将多条INSERT语句放入一个事务内,可以显著减少磁盘I/O次数,从而提升整体速度。例如: ```c++ sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL); for (int i = 0; i ; i++) { char sql...

    安卓SQLite数据库相关-实现对没填的工时记录操作android数据库sqlite.zip

    例如,当批量更新或插入数据时,可以开启一个事务,将一系列操作包裹在`beginTransaction()`、`setTransactionSuccessful()`和`endTransaction()`之间。 需要注意的是,描述中提到“程序如果跑不起来需要自调”,这...

    安卓SQLite数据库相关-Yahoo开源的SQLite数据库框架.rar

    Yahoo 开源的 SQLite 数据库框架,旨在简化 Android 应用中的 SQLite 数据库操作,提供更高级别的抽象层,帮助开发者更便捷地进行数据管理。这个框架可能包含了以下关键组件和特性: 1. **数据库帮助类(Database ...

    sqlite循环批量插入数据采用批处理文件实现

    总的来说,批处理文件是解决SQLite批量插入问题的一个实用方法,尤其是在没有DECLARE变量支持的情况下。但是,为了最佳性能和安全性,应考虑使用事务和编程语言提供的API。在实际应用中,根据具体需求和环境选择最...

    sqlitestudio-3.1.0

    2. **数据插入(Insert)**: 在创建了数据库和表之后,SQLiteStudio允许用户通过直观的界面输入数据,快速将记录插入到各个表格中,支持批量插入操作。 3. **数据查询(Query)**: 提供了SQL编辑器,用户可以编写...

    uniAPP使用sqlite数据库demo

    - 插入数据:使用`INSERT INTO`语句将新记录添加到表中。例如,`INSERT INTO students (name, age) VALUES ('张三', 20);` - 查询数据:使用`SELECT`语句获取表中的数据。例如,`SELECT * FROM students WHERE age...

Global site tag (gtag.js) - Google Analytics