Android数据库优化

一、索引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);


}

});

相关文章
相关标签/搜索