`

android:利用DatabaseUtils.InsertHelper提高insert速度

 
阅读更多

 

 Android OS中的DatabaseUtils.InsertHelper类提供的方法能够提高对sqlite数据库的insert速度 。但是,有关其使用的文档说明或者例子很少。希望这篇文章能有助于帮你揭开其神秘的面纱。
      我们经常有在SqliteOpenHelper的onCreate方法里面批量进行insert操作的情况,所以这个例子参照这种情景【已有隐式事务】 (批量处理意味着包含了有事务处理,我们知道,使用事务对程序的performance有影响,下面会有介绍)

假设onCreate方法如下:

private class DatabaseHelper extends SQLiteOpenHelper {
    @Override
    public void onCreate(SQLiteDatabase db) {
        ContentValues values = new ContentValues();
        while (moreRowsToInsert) {
            // ... create the data for this row (not shown) ...
           // Add the data for each column
            values.put( "Greek" , greekData);
            values.put( "Ionic" , ionicData);
            // ...
            values.put( "Roman" , romanData);  
            // Insert the row into the database.
            db.insert( "columnTable" , null , values);
        }
    }
    //...
}
 

 
使用DatabaseUtils.InsertHelper,则代码如下:

import android.database.DatabaseUtils.InsertHelper;
//...
private class DatabaseHelper extends SQLiteOpenHelper {
    @Override
    public void onCreate(SQLiteDatabase db) {
        // Create a single InsertHelper to handle this set of insertions.
        InsertHelper ih = new InsertHelper(db, "columnTable");
        // Get the numeric indexes for each of the columns that we're updating
        final int greekColumn = ih.getColumnIndex("Greek");
        final int ionicColumn = ih.getColumnIndex("Ionic");
        //...
        final int romanColumn = ih.getColumnIndex("Roman");
        while (moreRowsToInsert) {
            // ... Create the data for this row (not shown) ...
            // Get the InsertHelper ready to insert a single row
            ih.prepareForInsert();
            // Add the data for each column
            ih.bind(greekColumn, greekData);
            ih.bind(ionicColumn, ionicData);
            //...
            ih.bind(romanColumn, romanData);
            // Insert the row into the database.
            ih.execute();
        }
    }
    //...
}
 
     由以上代码可以看出,InsertHelper的使用比SQLiteDatabase.insert稍微复杂一点。最主要的区别是使用InertHelper时,
在使用adding("binding")添加对应列数据之前调用iH.prrepareForInsert()方法,并且需要对应列的index,
这个index值是通过循环里面调用ih.getColumnIndex()而获得。用DatabaseUtils.InsertHelper替换SQLiteDatabase.insert之后的代码,效率提升上大致相当于每秒95行和每秒525行数据插入速度。
   实际上InsrtHelper并没有做什么神奇的事情,它只是预编译语句的包装类,并且你自已也可以通过                  SQLiteDatabase.compileStatement来实现,很多人应该知道InsertHelper使用起来很容易
其他提高insert速度的方法
除此之外,通过对以下两个方面的优化,可以让插入速度提高到900行每秒,当然,这些技巧的使用是否有效和你的程序也有很大关系
1.不要绑定空列
在我的程序,至少有50%的列是空值。碰到空值列,就不调用ih.bind()方法对它进行绑定,就我的程序而言,当列值为null或者空的字符串是,
有将近30%的性能提升
2.临时关闭sqlitedatabase的同步锁检查功能
我在SQLiteOpenHelper.onCreate的方法中load数据库,在此期间,假如只有一个线程访问databaser,那么就不需要sqlite进行同步访问检查
所以,调用SQLiteDatabase.setLockingEnabled(false)
暂时将锁检查关闭。这个措施可以有35%的速度提升
public void onCreate(SQLiteDatabase db) {
    //...
    try 
    {
        // *Temporarily* (have I emphasized that enough?) disable
        // thread locking in the database. Be sure to re-enable locking
        // within a finally block.
        db.setLockingEnabled(false );
        // ... load the database ...
    }
    finally 
    {
        db.setLockingEnabled(true );
    }
 
事务和性能
很多人都知道显式使用事务控制的好处。??
然而,SQLiteOpenHelper在调用其回调函数(onCreate,onUpgrade,onOpen)之前已经创建了一个事务,因此,在这几个方法里面
没有必要显式声明一个事务控制(SQLiteOpenHelper默认事务已成功提交,除非方法里抛出exception)
如果insert操作不在SQLiteOpenHelper的上述回调方法中,那么你就可以使用显式的事务控制声明,主要使用的API有以下几个:
SQLiteDatabase.beginTransaction
SQLiteDatabase.setTransactionSuccessful
SQLiteDatabase.endTransaction.

可以在里面嵌套事务,不过,很明显它对性能的提升好像没什么帮助。实际上,嵌套事务甚至降低了程序的性能(大约1%,和测量精度有关)。试着周期性的关闭 当前事务--先关闭由SQLiteOpenHelper打开的事务-再打开一个新的。同样对性能的提升没有明显的作用,即便有也非常有限。
有些地方把握不准,恐有误导,欢迎斧正
贴上原文:Android: Using DatabaseUtils.InsertHelper for faster insertions into SQLite database

分享到:
评论

相关推荐

    DatabaseUtils工具包

    - `DatabaseUtils.insertHelper`: 这是一个帮助类,用于简化插入操作,可以避免创建ContentValues对象,直接传入参数进行插入。 4. **更新和删除操作**: - `DatabaseUtils.buildUpdateArgs(int[] indices, ...

    DatabaseUtils

    "DatabaseUtils"是一个在IT行业中常见的工具包,主要用于简化和标准化数据库操作。它提供了一系列的静态方法,使得开发者能够更加高效、便捷地处理与数据库相关的任务。在这个工具包中,通常包括了对SQL语句的构造、...

    kkt-containing.rar_Internet/IE编程_kkt_kkt 代码

    1. `DatabaseUtils.props.hsql`:这是一个与数据库操作相关的属性文件,可能包含连接HSQLDB(一个纯Java关系型数据库)的配置信息。HSQLDB常被用作测试数据库,因为它轻量级且易于使用。 2. `PairedTTester.java`:...

    hzl.rar_jxta开发

    1. **DatabaseUtils.props.hsql**:这可能是一个配置文件,用于设置数据库连接参数,特别是针对HSQLDB(一个纯Java的嵌入式数据库)的连接。在JXTA开发中,可能需要存储和检索数据,此文件可能是数据库访问层的一...

    android解决乱码

    可以使用`DatabaseUtils.sqlEscapeString()`进行转码。 5. Android Studio配置:在Android Studio中,确保项目资源文件的编码设置正确,通常推荐使用UTF-8。在项目设置中,检查`File Encodings`选项,确保全局、...

    MySQL+jsp网上购物系统源码 MYSQLJSPWSGWXT.rar

    MySQL+jsp网上购物系统源码 源码描述: 一、源码介绍 MySQL+jsp网上购物系统源码使用servlet,... 修改DataBaseUtils.java 二、主要功能 用户注册,登录,浏览商品。 三、注意事项 开发环境为jdk1.7,数据库为mysql

    (完整版)电子相册管理系统毕业论文.pdf

    本文主要探讨如何利用Jsp、Servlet、MySQL等技术开发一个完整的电子相册管理系统。 一、系统概述 电子相册管理系统是一个基于Web的应用程序,旨在为用户提供便捷的照片存储、分类、查看以及评论互动的平台。系统...

    android工具类

    Android工具类是为了简化代码复用和提高代码质量而设计的。它们可以处理各种通用任务,如数据验证、UI操作、日志打印等。通常,工具类遵循单一职责原则,即每个工具类只负责一种特定的功能。例如,一个`...

    flex 实现图片另存为

    var byteArr: ByteArray = DataBaseUtils.BitmapDataToByteArray(myImage); var width: Number = myImage.width; var height: Number = myImage.height; // 使用JPEG编码器压缩ByteArray byteArr = new ...

    留言板 jsp jdbc

    4. `util/DatabaseUtils.java`:数据库工具类,封装了JDBC的数据库连接、关闭等操作。 5. `sql/`:可能包含数据库建表脚本,如`create_table.sql`,用于创建留言板表。 6. `css/` 和 `js/`:分别存放样式表和...

    安卓开发框架工具类相关-androiddb工具类.zip

    因此,许多开发者会创建自定义的工具类,如`DBHelper`或`DatabaseUtils`,来封装这些底层操作,提高代码的可读性和可维护性。 在`useDB`这个文件夹中,可能包含了一系列用于操作数据库的工具类,例如`DBManager`...

    Weka连接访问MySQL数据库的办法

    导入`weka.jar`文件,并找到`DatabaseUtils.props`文件。此文件位于`weka.jar\weka\experiment\xml`路径下。在这个文件中,修改`jdbcDriver`和`jdbcURL`的值以适应MySQL配置。例如,`jdbcDriver=...

    Weka开发----在代码中使用Weka.pdf

    确保JDBC驱动已添加到类路径,并正确配置`DatabaseUtils.props`文件。 总结,Weka提供了丰富的API来支持数据处理、模型构建与评估。通过实例化这些组件并调用相应的方法,可以在代码中灵活地集成机器学习功能。注意...

    java数据库封装类

    4. 当需要使用数据库时,只需调用`DatabaseUtils.getConnection(config)`即可获取到数据库连接。 至于`UserLogin_regDemo`这个文件,可能是数据库封装类的一个注册登录的演示示例。在这个场景下,开发者可能会创建...

    摆脱Mapper的mybatis-plus,封装stream和lambda操作进行数据返回处理

    List<User> users = DatabaseUtils.queryByLambda(User.class, (LambdaQueryWrapper<User> wrapper) -> wrapper.eq(User::getId, 1) .or() .like(User::getName, "John")) .stream() .filter(user -> user....

    Android SQLiteDatabase的使用详解

    ### Android SQLiteDatabase的使用详解 在Android开发过程中,`SQLiteDatabase`是进行本地数据存储的核心类之一,它提供了创建和查询SQLite数据库的方法。SQLite是一种轻量级的嵌入式数据库引擎,广泛应用于移动...

    一篇不错的关于java工作流方面讲解及代码

    5.4.4 数据库连接的关闭(DatabaseUtils.java)--只提供接口 23 5.4.5 密码修改模块(Common_fuction.java) 24 5.4.6 时间格式转换(timeBean.java) 24 5.4.7 数据统计(counthander.java) 25 5.4.8 营业厅的接口...

    安卓工具类整理

    在Android开发中,工具类(Util)是一种封装了常用功能的方法集合,可以帮助开发者更高效地编写代码,提高代码的可重用性和可维护性。以下是对"安卓工具类整理"这个主题的详细说明: 1. **字符串处理工具类**: - ...

    java中调用weka

    首先,我们需要修改DatabaseUtils.props文件,添加数据库连接信息。例如,我们可以使用以下代码来连接MySQL服务器: ```java jdbcDriver=org.gjt.mm.mysql.Driver jdbcURL=jdbc:mysql://localhost:3306/some_...

Global site tag (gtag.js) - Google Analytics