Android 性能优化 (二)数据库优化 秒变大神
来源:互联网 发布:unity3d 录屏插件 编辑:程序博客网 时间:2024/06/05 05:14
Android 性能优化 (一)APK高效瘦身
http://blog.csdn.net/whb20081815/article/details/70140063
Android 性能优化(三)布局优化 秒变大神
http://blog.csdn.net/whb20081815/article/details/70147958
Android 性能优化<七>自定义view绘制优化
1.数据库插入效率
2)借用ContentValues进行插入;
3)使用compileStatement进行插入;
1)直接拼接SQL语句,执行execSQL方法, 一个一个插入
/** * 向表中插入数据 * * @param openHelper * @param appInfo * @return */public static boolean insert(SQLiteOpenHelper openHelper, RemoteAppInfo appInfo) { if (null == appInfo) { return true; } SQLiteDatabase db = null; try { db = openHelper.getWritableDatabase(); ContentValues values = appInfo.getContentValues(); return -1 != db.insert(RemoteDBHelper.TABLE_APP_REMOTE, null, values); } catch (Exception e) { e.printStackTrace(); } finally { if (null != db) { db.close(); } } return false;}for (RemoteAppInfo remoteAppInfo : list){ RemoteDBUtil.insert(helper, remoteAppInfo);}
public void execSQL(){ String sql = "create table msgTable(uid INTEGER NOT NULL, msg TEXT NOT NULL)"; db.execSQL(sql);}缺点:存在SQL注入危险;
查看源码得出:execSQL调用的本质就是创建SQLiteStatement对象,调用其executeUpdateDelete插入方法
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等函数效率高。当数据库越大,差别也越大。
二.开启事务批量插入,借用ContentValues;
这样如果连续插入100次数据实际是创建事务->执行语句->提交这个过程被重复执行了100次。如果我们显示的创建事务->执行100条语句->提交会使得这个创建事务和提交这个过程只做一次,通过这种一次性事务可以使得性能大幅提升。尤其当数据库位于sd卡时,时间上能节省两个数量级左右。
/** * 向表中插入一串数据 * * @param openHelper * @param appInfo * @return 如果成功则返回true,否则返回flase */public static boolean insert(SQLiteOpenHelper openHelper, List<RemoteAppInfo> list) { boolean result = true; if (null == list || list.size() <= 0) { return true; } SQLiteDatabase db = null; try { db = openHelper.getWritableDatabase(); db.beginTransaction(); for (RemoteAppInfo remoteAppInfo : list) { ContentValues values = remoteAppInfo.getContentValues(); if (db.insert(RemoteDBHelper.TABLE_APP_REMOTE, null, values) < 0) { result = false; break; } } if (result) { db.setTransactionSuccessful(); } } catch (Exception e) { e.printStackTrace(); return false; } finally { try { if (null != db) { db.endTransaction(); db.close(); } } catch (Exception e) { e.printStackTrace(); } } return true;}借用ContentValues进行插入,解决了执行纯SQL语句引入的sql注入漏洞。
源码分析:使用ContentValues 最终是创建SQLiteStatement对象,并调用executeInsert()方法。
三,compileStatement,开启事务批量插入,使用SQLiteStatement
public static boolean insertBySql(SQLiteOpenHelper openHelper, List<RemoteAppInfo> list) { if (null == openHelper || null == list || list.size() <= 0) { return false; } SQLiteDatabase db = null; try { db = openHelper.getWritableDatabase(); String sql = "insert into " + RemoteDBHelper.TABLE_APP_REMOTE + "(" + RemoteDBHelper.COL_PKG_NAME + ","// 包名 + RemoteDBHelper.COL_USER_ACCOUNT + ","// 账号 + RemoteDBHelper.COL_APP_SOURCE + ","// 来源 + RemoteDBHelper.COL_SOURCE_UNIQUE + ","// PC mac 地址 + RemoteDBHelper.COL_MOBILE_UNIQUE + ","// 手机唯一标识 + RemoteDBHelper.COL_IMEI + ","// 手机IMEI + RemoteDBHelper.COL_INSTALL_STATUS + ","// 安装状态 + RemoteDBHelper.COL_TRANSFER_RESULT + ","// 传输状态 + RemoteDBHelper.COL_REMOTE_RECORD_ID // 唯一标识 + ") " + "values(?,?,?,?,?,?,?,?,?)"; SQLiteStatement stat = db.compileStatement(sql); db.beginTransaction(); for (RemoteAppInfo remoteAppInfo : list) { stat.bindString(1, remoteAppInfo.getPkgName()); stat.bindString(2, remoteAppInfo.getAccount()); stat.bindLong(3, remoteAppInfo.getFrom()); stat.bindString(4, remoteAppInfo.getFromDeviceMd5()); stat.bindString(5, remoteAppInfo.getMoblieMd5()); stat.bindString(6, remoteAppInfo.getImei()); stat.bindLong(7, remoteAppInfo.getInstallStatus()); stat.bindLong(8, remoteAppInfo.getTransferResult()); stat.bindString(9, remoteAppInfo.getRecordId()); long result = stat.executeInsert(); if (result < 0) { return false; } } db.setTransactionSuccessful(); } catch (Exception e) { e.printStackTrace(); return false; } finally { try { if (null != db) { db.endTransaction(); db.close(); } } catch (Exception e) { e.printStackTrace(); } } return true;}
SQLiteStatement stat = TelSqlAdapter.getInstance().getSqliteDb().compileStatement(sql);
小结:对于执行纯sql,ContentValues和compileStatement最终都是new 一个SQLiteStatement对象,并调用SQLiteStatement对象的相应方法。
无论哪种方法的话,都会用SQLiteStatement,直接用这个看,
=========================================
其他方式:
1)。语句的拼接使用StringBuilder代替String
简单的string相加会导致创建多个临时对象消耗性能。StringBuilder的空间预分配性能好得多。如果你对字符串的长度有大致了解,如100字符左右,可以直接new StringBuilder(128)指定初始大小,减少空间不够时的再次分配。
2)。少用cursor.getColumnIndex
根据性能调优过程中的观察cursor.getColumnIndex的时间消耗跟cursor.getInt相差无几。可以在建表的时候用static变量记住某列的index,直接调用相应index而不是每次查询。
3)。查询条件多点限制,查表就速度快
1.数据库的操作类型有哪些,如何导入外部数据库?
把原数据库包括在项目源码的 res/raw。android系统下数据库应该存放在 /data/data/com..(package name)/ 目录下,所以我们需要做的是把已有的数据库传入那个目录下.操作方法是用FileInputStream读取原数据库,再用FileOutputStream把读取到的东西写入到那个目录.
- Android 性能优化 (二)数据库优化 秒变大神
- Android 性能优化(三)布局优化 秒变大神
- Android 性能优化(五)ANR 秒变大神
- Android 内存优化OOM 秒变大神 内存泄漏_ 性能优化(四)
- android性能优化---数据库优化
- 数据库性能优化二:数据库表优化
- 数据库性能优化二:数据库表优化
- 数据库性能优化二:数据库表优化
- 数据库性能优化二:数据库表优化
- 数据库性能优化二:数据库表优化
- 数据库性能优化二:数据库表优化
- 数据库性能优化二:数据库表优化
- 数据库性能优化二:数据库表优化
- 数据库性能优化二:数据库表优化
- 数据库性能优化二:数据库表优化
- 数据库性能优化二:数据库表优化
- 数据库性能优化二:数据库表优化
- android 性能优化二
- appium命令行启动和停止
- 查找文本文件中的关键字
- 数据连接池——JNDI
- 烦人的dp
- html中offsetTop、clientTop、scrollTop、offsetTop各属性介绍
- Android 性能优化 (二)数据库优化 秒变大神
- D. Block Tower
- Stock 贪心经典 Zoj2921
- 二分
- Loadrunner编辑脚本一些技巧
- Data Handler 大模拟 + 双端链表 hdu 4268
- Maze Stretching Poj3897 二分+BFS
- 【转】别人家的八数码 A* IDA*解法
- CodeForces 25D Roads not only in Berland