一、索引android
简单的说,索引就像书本的目录,目录能够快速找到所在页数,数据库中索引能够帮助快速找到数据,而不用全表扫描,合适的索引能够大大提升数据库查询的效率。
(1). 优势
大大加快了数据库检索的速度,包括对单表查询、连表查询、分组查询、排序查询。常常是一到两个数量级的性能提高,且随着数据数量级增加。sql
(2). 缺点
索引的建立和维护存在消耗,索引会占用物理空间,且随着数据量的增长而增长。
在对数据库进行增删改时须要维护索引,因此会对增删改的性能存在影响。
数据库
二、使用事务
使用事务的两大好处是原子提交和更优性能。
(1) 原子提交
原则提交意味着同一事务内的全部修改要么都完成要么都不作,若是某个修改失败,会自动回滚使得全部修改不生效。多线程
(2) 更优性能
Sqlite默认会为每一个插入、更新操做建立一个事务,而且在每次插入、更新后当即提交。并发
这样若是连续插入100次数据实际是建立事务->执行语句->提交这个过程被重复执行了100次。若是咱们显示的建立事务->执行100条语句->提交会使得这个建立事务和提交这个过程只作一次,经过这种一次性事务可使得性能大幅提高。尤为当数据库位于sd卡时,时间上能节省两个数量级左右。异步
Sqlte显示使用事务,示例代码以下:ide
public void insertWithOneTransaction() {
SQLiteDatabase db = sqliteOpenHelper.getWritableDatabase();
// Begins a transaction
db.beginTransaction();
try {
// your sqls
for (int i = 0; i < 100; i++) {
db.insert(yourTableName, null, value);
}
// marks the current transaction as successful
db.setTransactionSuccessful();
} catch (Exception e) {
// process it
e.printStackTrace();
} finally {
// end a transaction
db.endTransaction();
}
}
其中sqliteOpenHelper.getWritableDatabase()表示获得写表权限。性能
三、其余针对Sqlite的优化
(1) 语句的拼接使用StringBuilder代替String
这个就很少说了,简单的string相加会致使建立多个临时对象消耗性能。StringBuilder的空间预分配性能好得多。若是你对字符串的长度有大体了解,如100字符左右,能够直接new StringBuilder(128)指定初始大小,减小空间不够时的再次分配。优化
(2) 查询时返回更少的结果集及更少的字段。
查询时只取须要的字段和结果集,更多的结果集会消耗更多的时间及内存,更多的字段会致使更多的内存消耗。ui
(3)cursor使用后要及时关闭:即在查询完结果后,调用cursor.close()将资源关闭。
(4) 少用cursor.getColumnIndex
根据性能调优过程当中的观察cursor.getColumnIndex的时间消耗跟cursor.getInt相差无几。能够在建表的时候用static变量记住某列的index,直接调用相应index而不是每次查询。
public static final String HTTP_RESPONSE_TABLE_ID =android.provider.BaseColumns._ID;
public static final String HTTP_RESPONSE_TABLE_RESPONSE ="response";
publicList<Object>getData(){
……
cursor.getString(cursor.getColumnIndex(HTTP_RESPONSE_TABLE_RESPONSE));
……
}
优化为
public static final String HTTP_RESPONSE_TABLE_ID = android.provider.BaseColumns._ID;
public static final String HTTP_RESPONSE_TABLE_RESPONSE = "response";
public static final int HTTP_RESPONSE_TABLE_ID_INDEX = 0;
public static final int HTTP_RESPONSE_TABLE_URL_INDEX = 1;
public List<Object> getData() {
……
cursor.getString(HTTP_RESPONSE_TABLE_RESPONSE_INDEX);
……
}
四、异步线程
Android中数据很少时表查询可能耗时很少,不会致使anr,不过大于100ms时一样会让用户感受到延时和卡顿,能够放在线程中运行,但sqlite在并发方面存在局限,多线程控制较麻烦,这时候可以使用单线程池,在任务中执行db操做,经过handler返回结果和ui线程交互,既不会影响UI线程,同时也能防止并发带来的异常。
可以使用Android提供的AsyncQueryHandler(感谢@内网没法登录帐号 反馈)或相似以下代码完成:
ExecutorService singleThreadExecutor=Executors.newSingleThreadExecutor();
singleThreadExecutor.execute(newRunnable(){
@Override
publicvoidrun(){
//
db operetions, u can use handler to send message after
db.insert(yourTableName,null,value);
handler.sendEmptyMessage(xx);
}
});