您的位置:首页 > 数据库

论execSQL与executeInsert执行效率之差

2014-03-21 02:04 302 查看
 
       看到一遍关于SQLiteDatabase 的execSQL方法和SQLiteStatement的executeInsert的执行效率之比。文中最终得出结论后者比前者效率高,带着疑惑的心态让验证了一把却得出了截然相反的结论。无论在数据量大小或则是否开启事务操作上SQLiteDatabase
的execSQL的执行效率还是要比SQLiteStatement的executeInsert高。

以下就是我所做的一个验证过程

     新建一个数据库和test表

public class DBhelper extends SQLiteOpenHelper {
private static final String DATABAS_NAME = "testdb";
private static final int DATABAS_VERSION = 1;
public DBhelper(Context context) {
super(context, DATABAS_NAME, null, DATABAS_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
StringBuffer sql  =new StringBuffer();
sql.append("create table test");
sql.append("(_id int PRIMARY KEY,name varchar,gender int,age int,phoneNumber varchar,address varchar)");
db.execSQL(sql.toString());
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}
}
使用SQLiteDatabase 的execSQL方法和SQLiteStatement的executeInsert方法进入插入,
比较执行所需要的时间:

public class Dao {
private DBhelper dbHelper;
private SQLiteDatabase db;
private StringBuffer sql_insert;
private List<Tester> testers;

public Dao(Context context) {
this.dbHelper = new DBhelper(context);
this.db = dbHelper.getWritableDatabase();
sql_insert = new StringBuffer();
sql_insert
.append("INSERT INTO test(name,gender,age,phoneNumber,address) ");
sql_insert.append(" VALUES( ?, ?, ?, ?, ?)");
testers = new ArrayList<Tester>();
// 测试数据
for (int i = 0; i < 1000; i++) {
Tester tester = new Tester();
tester.setId(i);
tester.setName("name" + i);
tester.setGender(0);
tester.setAge(123);
tester.setPhoneNumber("123456789");
tester.setAddress("zhejiang ningbo ." + i);

testers.add(tester);
}

}

/**
* 使用SQLiteDatabase 的execSQL方法插入数据
*/
public long insertexecSQL() {

long start = System.currentTimeMillis();

db.beginTransaction();
try {
for (Tester tester : testers) {
Object[] bindArgs = { tester.getName(), tester.getGender(),
tester.getAge(), tester.getPhoneNumber(),
tester.getAddress() };
db.execSQL(sql_insert.toString(), bindArgs);
}
db.setTransactionSuccessful();
} catch (SQLException e) {

}finally{
db.endTransaction();
}

long end = System.currentTimeMillis();

return end - start;
}

/**
* 使用SQLiteStatement的executeInsert方法插入数据
*/
public long insertStatement() {
long start = System.currentTimeMillis();
db.beginTransaction();
try {
for (Tester tester : testers) {
SQLiteStatement statement = db.compileStatement(sql_insert
.toString());
statement.bindString(1, tester.getName());
statement.bindLong(2, tester.getGender());
statement.bindLong(3, tester.getAge());
statement.bindString(4, tester.getPhoneNumber());
statement.bindString(5, tester.getAddress());
statement.executeInsert();
}
db.setTransactionSuccessful();
} catch (SQLException e) {

}finally{
db.endTransaction();
}
long end = System.currentTimeMillis();
return end - start;
}

}

两个按钮,分别调用不同的插入方法, 并将执行所需的时间显示在Button上

public class MainActivity extends Activity {
private Button btn1;
private Button btn2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Dao dao = new Dao(MainActivity.this);
btn1 = (Button) findViewById(R.id.button1);
btn2 = (Button) findViewById(R.id.button2);
btn1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
btn1.setText(String.valueOf(dao.insertexecSQL()));
}
});
btn2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
btn2.setText(String.valueOf(dao.insertStatement()));
}
});
}
}

通过几次比较发现,在实际实验后得出的数据是SQLiteStatement的executeInsert并没有使用SQLiteDatabase 的execSQL方法快,以下为其中一次的秒数截图,上面按钮显示调用的方法为SQLiteDatabase
的execSQL,下面按钮则是SQLiteStatement的executeInsert。



循环插入100条数据



循环插入1000条数据后



在使用事务循环插入1000条数据后



从上面的数据可以看出,随着数据量的增大,SQLiteDatabase
的execSQL的执行效率远比SQLiteStatement的executeInsert高,差距非常大。

同时在对其开启事务后,执行效率也大幅提高,只逼循环插入100条数据所需的时间。

db.beginTransaction();
db.setTransactionSuccessful();
db.endTransaction();
以上操做在测试时均未使用异步类或开启新线程,在插入1000条数据时候,出现非常长的停顿现象,随着数据量的逐步增加非常容易直接停止响应。

所以建议,在进行大数据操作时候,使用异步或开启新线程的同时也有必要对其开启事务。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息