假设现在有一个这样的简单场景, 就是向一个数据库中插入2000数据,我们怎么优化呢?
1,直接插入方式
private void insert(){
SQLiteDatabase db = mHelper.getWritableDatabase();
long startTime = System.currentTimeMillis();
String sql = "insert into person values(?,?)";
for(int i=0; i<2000; i++){
db.execSQL(sql,new Object[]{"Tom"+i,i});
}
long usedTime = System.currentTimeMillis() - startTime;
Log.i("tag","usedTime = "+usedTime);
}
结果是:usedTime = 9515
2,预编译
采用直接插入方式时间将近10s,我们下面采用预编译方式进行优化.采用预编译sql的方式, sql只编译一次, 在插入时,绑定插入数据即可
private void insert(){
SQLiteDatabase db = mHelper.getWritableDatabase();
long startTime = System.currentTimeMillis();
String sql = "insert into person values(?,?)";
SQLiteStatement statement = db.compileStatement(sql);
for(int i=0; i<2000; i++){
statement.bindString(1, "Tom"+i);
statement.bindString(1, i+"");
statement.execute();
}
statement.clearBindings();
statement.close();
long usedTime = System.currentTimeMillis() - startTime;
Log.i("tag","usedTime = "+usedTime);
}
结果是:usedTime = 8370
由1和2对比分析可知,优化的效果不是太明显
3,通过事务的方式优化
private void insert(){
SQLiteDatabase db = mHelper.getWritableDatabase();
long startTime = System.currentTimeMillis();
db.beginTransaction();
String sql = "insert into person values(?,?)";
for(int i=0; i<2000; i++){
db.execSQL(sql,new Object[]{"Tom"+i,i});
}
db.setTransactionSuccessful();
db.endTransaction();
long usedTime = System.currentTimeMillis() - startTime;
Log.i("tag","usedTime = "+usedTime);
}
结果是:usedTime =173
通过开启事务这个例子可知道, 通过事务开启来优化数据库的批量数据操作,是最根本和最有效的
那么什么是事务呢? 事务的标准定义: 指作为单个逻辑工作单元执行的一系列操作,而这些逻辑工作单元需要具有原子性, 一致性,隔离性和持久性四个属性,统称为ACID特性。所谓事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位。例如,在关系数据库中,一个事务可以是一条SQL语句、一组SQL语句或整个程序。
在说说数据库事务的四大特性:
原子性(Atomic)
事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行
一致性(Consistent)
事务在完成时,必须使所有的数据都保持一致状态
隔离性(Insulation)
由并发事务所作的修改必须与任何其它并发事务所作的修改隔离
持久性(Duration)
事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。
4,使用事务加预编译sql方式
private void insert() {
SQLiteDatabase db = mHelper.getWritableDatabase();
long startTime = System.currentTimeMillis();
try{
String sql = "insert into person values(?,?)";
SQLiteStatement statement = db.compileStatement(sql);
db.beginTransaction();
for (int i = 0; i < 2000; i++) {
statement.bindString(1, "Tom" + i);
statement.bindString(2, i + "");
statement.execute();
}
statement.close();
db.setTransactionSuccessful();
db.endTransaction();
}catch(Exception e){
System.out.println(e.toString());
}
long usedTime = System.currentTimeMillis() - startTime;
Log.i("tag", "usedTime = " + usedTime);
}
运行结果:结果是:usedTime =114
所以在android批量操作sqlite数据时候要使用事务这个快速之王, 预编译sql等手段. 如果sql语句比较长可以使用StringBuffer等拼接.