[转]android:利用DatabaseUtils.InsertHelper提高insert速度
16lz
2021-01-23
android:利用DatabaseUtils.InsertHelper提高insert速度insertandroidlockingsqlitedatabaseexception 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.beginTransactionSQLiteDatabase.setTransactionSuccessfulSQLiteDatabase.endTransaction. 可以在里面嵌套事务,不过,很明显它对性能的提升好像没什么帮助。实际上,嵌套事务甚至降低了程序的性能(大约1%,和测量精度有关)。试着周期性的关闭当前事务--先关闭由SQLiteOpenHelper打开的事务-再打开一个新的。同样对性能的提升没有明显的作用,即便有也非常有限。有些地方把握不准,恐有误导,欢迎斧正贴上原文:Android: Using DatabaseUtils.InsertHelper for faster insertions into SQLite database
更多相关文章
- android 获取路径目录方法 以及 获取路径方法
- Linux系统下安装android sdk的方法步骤
- 选项卡使用方法二(Android学习随笔十三)
- 使用AndroidStudio编译NDK的方法及错误解决方式
- Android Studio 配置快捷方式生成JNI头文件的方法
- android 读取DDMS里的文件时打不开,解决方法
- Android:Manifest merger failed with multiple errors, see log
- android中真正destroy掉activity的方法
- Android旋转屏幕不销毁数据的方法