利用android提高的的insert,query,update,deleteAPI与execSql,rawQuery函数执行原生的插入,查询,更新,删除语

转载地址: http://m.blog.csdn.net/blog/tigriswing/36440033

   1.利用android提高的的insert,query,update,deleteAPI与execSql,rawQuery函数执行原生的插入,查询,更新,删除语句操作花费时间的对比结果

    在相同的环境(adnroid4.0)和相同的机器下执行相同的动作,记录条数也一样的情况下的对比,多次验证的如下:

    (1)如果批量执行的记录数在1000条,则Android SqliteDatabase提供的insert,query,update,delete函数和直接写SQL文的execSql,rawQuery的效率差不多,几乎一样。所以使用哪种放到都可以,不会影响到执行效率。

    (2)如果批量执行的记录数在10万条,则会存在差别。在某台手机上SqliteDatabase提供的insert执行插入操作耗时45秒,要比execSql插入35秒慢10秒左右。

    可见在数据库大的情况下,还是有差别的。execSql省去了拼接sql语句的步骤,要比SqliteDatabase提供的insert,query,update,delete等函数效率高。当数据库越大,差别也越大。

2.Sqlite数据库批量操作效率的问题

应用程序初始化时需要批量的向sqlite中插入大量数据,单独的使用for+Insert方法导致应用响应缓慢, 因为  SQLite的数据库本质上来讲就是一个磁盘上的文件,所以一切的数据库操作其实都会转化为对文件的操作,而频繁的文件操作将会是一个很耗时的过程,会极大地影响数据库存取的速度。sqlite插入数据的时候默认一条语句就是一个事务,有多少条数据就有多少次磁盘操作。初始5000条记录也就是要5000次读写磁盘操作, 将会重复的打开关闭数据库文件5000次,所以速度当然会很慢。而且不能保证所有数据都能同时插入。

    解决方法:

    添加事务处理,把5000条插入作为一个事务

    我们使用SQLite的事务进行控制:

        db.beginTransaction();  //手动设置开始事务

        try{

            //批量处理操作

            for(Collection c:colls){

                insert(db, c);

            }

            db.setTransactionSuccessful(); //设置事务处理成功,不设置会自动回滚不提交。

//在setTransactionSuccessful和endTransaction之间不进行任何数据库操作 

           }catch(Exception e){

               MyLog.printStackTraceString(e);

           }finally{

               db.endTransaction(); //处理完成

           }

    这样SQLite将把全部要执行的SQL语句先缓存在内存当中,然后等到COMMIT的时候一次性的写入数据库,这样数据库文件只被打开关闭了一次,效率自然大大的提高




对比在android中批量插入数据的3中方式对比(各插入1W条数据所花费的时间):

1、 一个一个插入

Java代码  
  1. /**
  2.      * 向表中插入数据
  3.      * 
  4.      * @param openHelper
  5.      * @param appInfo
  6.      * @return
  7.      */
  8. publicstaticboolean insert(SQLiteOpenHelper openHelper,  
  9.             RemoteAppInfo appInfo) {  
  10. if (null == appInfo) {  
  11. returntrue;  
  12.         }  
  13.         SQLiteDatabase db = null;  
  14. try {  
  15.             db = openHelper.getWritableDatabase();  
  16.             ContentValues values = appInfo.getContentValues();  
  17. return -1 != db.insert(RemoteDBHelper.TABLE_APP_REMOTE, null,  
  18.                     values);  
  19.         } catch (Exception e) {  
  20.             e.printStackTrace();  
  21.         } finally {  
  22. if (null != db) {  
  23.                 db.close();  
  24.             }  
  25.         }  
  26. returnfalse;  
  27.     }  
  28. for (RemoteAppInfo remoteAppInfo : list) {  
  29.                     RemoteDBUtil.insert(helper, remoteAppInfo);  
  30.                 }  

 耗时:106524ms,也就是106s

2、 开启事务批量插入,使用

SqliteDateBase中的

insert(String table, String nullColumnHack, ContentValues values)

方法

Java代码  
  1. /**
  2.  * 向表中插入一串数据
  3.  * 
  4.  * @param openHelper
  5.  * @param appInfo
  6.  * @return 如果成功则返回true,否则返回flase
  7.  */
  8. publicstaticboolean insert(SQLiteOpenHelper openHelper,  
  9.         List list) {  
  10. boolean result = true;  
  11. if (null == list || list.size() < span>0) {  
  12. returntrue;  
  13.     }  
  14.     SQLiteDatabase db = null;  
  15. try {  
  16.         db = openHelper.getWritableDatabase();  
  17.         db.beginTransaction();  
  18. for (RemoteAppInfo remoteAppInfo : list) {  
  19.             ContentValues values = remoteAppInfo.getContentValues();  
  20. if (db.insert(RemoteDBHelper.TABLE_APP_REMOTE, null, values) < span>0) {  
  21.                 result = false;  
  22. break;  
  23.             }  
  24.         }  
  25. if (result) {  
  26.             db.setTransactionSuccessful();  
  27.         }  
  28.     } catch (Exception e) {  
  29.         e.printStackTrace();  
  30. returnfalse;  
  31.     } finally {  
  32. try {  
  33. if (null != db) {  
  34.                 db.endTransaction();  
  35.                 db.close();  
  36.             }  
  37.         } catch (Exception e) {  
  38.             e.printStackTrace();  
  39.         }  
  40.     }  
  41. returntrue;  
  42. }  

耗时:2968ms

3、 开启事务批量插入,使用

SQLiteStatement

Java代码  
  1. /**
  2.      * 第二种方式批量插入(插入1W条数据耗时:1365ms)
  3.      * @param openHelper
  4.      * @param list
  5.      * @return
  6.      */
  7. publicstaticboolean insertBySql(SQLiteOpenHelper openHelper,  
  8.             List list) {  
  9. if (null == openHelper || null == list || list.size() < span>0) {  
  10. returnfalse;  
  11.         }  
  12.         SQLiteDatabase db = null;  
  13. try {  
  14.             db = openHelper.getWritableDatabase();  
  15.             String sql = "insert into " + RemoteDBHelper.TABLE_APP_REMOTE + "("
  16.                     + RemoteDBHelper.COL_PKG_NAME + ","// 包名
  17.                     + RemoteDBHelper.COL_USER_ACCOUNT + ","// 账号
  18.                     + RemoteDBHelper.COL_APP_SOURCE + ","// 来源
  19.                     + RemoteDBHelper.COL_SOURCE_UNIQUE + ","// PC mac 地址
  20.                     + RemoteDBHelper.COL_MOBILE_UNIQUE + ","// 手机唯一标识
  21.                     + RemoteDBHelper.COL_IMEI + ","// 手机IMEI
  22.                     + RemoteDBHelper.COL_INSTALL_STATUS + ","// 安装状态
  23.                     + RemoteDBHelper.COL_TRANSFER_RESULT + ","// 传输状态
  24.                     + RemoteDBHelper.COL_REMOTE_RECORD_ID // 唯一标识
  25.                     + ") " + "values(?,?,?,?,?,?,?,?,?)";  
  26.             SQLiteStatement stat = db.compileStatement(sql);  
  27.             db.beginTransaction();  
  28. for (RemoteAppInfo remoteAppInfo : list) {  
  29.                 stat.bindString(1, remoteAppInfo.getPkgName());  
  30.                 stat.bindString(2, remoteAppInfo.getAccount());  
  31.                 stat.bindLong(3, remoteAppInfo.getFrom());  
  32.                 stat.bindString(4, remoteAppInfo.getFromDeviceMd5());  
  33.                 stat.bindString(5, remoteAppInfo.getMoblieMd5());  
  34.                 stat.bindString(6, remoteAppInfo.getImei());  
  35.                 stat.bindLong(7, remoteAppInfo.getInstallStatus());  
  36.                 stat.bindLong(8, remoteAppInfo.getTransferResult());  
  37.                 stat.bindString(9, remoteAppInfo.getRecordId());  
  38. long result = stat.executeInsert();  
  39. if (result < span>0) {  
  40. returnfalse;  
  41.                 }  
  42.             }  
  43.             db.setTransactionSuccessful();  
  44.         } catch (Exception e) {  
  45.             e.printStackTrace();  
  46. returnfalse;  
  47.         } finally {  
  48. try {  
  49. if (null != db) {  
  50.                     db.endTransaction();  
  51.                     db.close();  
  52.                 }  
  53.             } catch (Exception e) {  
  54.                 e.printStackTrace();  
  55.             }  
  56.         }  
  57. returntrue;  
  58.     }  

耗时:1365ms

你可能感兴趣的:(利用android提高的的insert,query,update,deleteAPI与execSql,rawQuery函数执行原生的插入,查询,更新,删除语)