MyException - 我的异常网
当前位置:我的异常网» 数据库 » android:利用DatabaseUtils.InsertHelper拔高inser

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

www.MyException.Cn  网友分享于:2013-07-02  浏览:68次
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

文章评论

团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
程序员的鄙视链
程序员的鄙视链
代码女神横空出世
代码女神横空出世
我的丈夫是个程序员
我的丈夫是个程序员
一个程序员的时间管理
一个程序员的时间管理
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
如何成为一名黑客
如何成为一名黑客
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
编程语言是女人
编程语言是女人
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
那些争议最大的编程观点
那些争议最大的编程观点
我是如何打败拖延症的
我是如何打败拖延症的
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
每天工作4小时的程序员
每天工作4小时的程序员
程序员必看的十大电影
程序员必看的十大电影
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
老程序员的下场
老程序员的下场
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
为什么程序员都是夜猫子
为什么程序员都是夜猫子
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
旅行,写作,编程
旅行,写作,编程
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
中美印日四国程序员比较
中美印日四国程序员比较
程序员都该阅读的书
程序员都该阅读的书
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
程序员应该关注的一些事儿
程序员应该关注的一些事儿
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
漫画:程序员的工作
漫画:程序员的工作
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
10个调试和排错的小建议
10个调试和排错的小建议
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
程序员和编码员之间的区别
程序员和编码员之间的区别
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有