假设我有一个网格视图,其中包含很多项。网格视图中的项目可以通过拖放来调整。洗牌完成后,我想将项目的顺序存储在数据库中,以便以后可以读取它以恢复相同的顺序。
我的思维过程是把订单分配给每个项目,当洗牌完成时,我计划用新的订单更新数据库中的所有相关记录。但是,运行许多更新查询似乎太昂贵了。请用一种优化的技术建议我完成这项任务。提前谢谢。
发布于 2014-07-21 08:17:51
SQLite中的大多数性能问题来自于在自己的事务中执行每个命令的额外开销。如果你就这么做:
final SQLiteDatabase database = this.openHelper.getWritableDatabase();
for(Entity entities : viewModels) {
// Perform your updates here
ContentValues contentValues = EntityConverter.toContentValues(entity);
database.update(table, contentValues, "_id = ?", entity.getId());
}然后在一个单独的事务中执行对update(...)的每个调用。如果您只想更新3或4行,这并不重要,但是如果您想要更新数百行甚至数千行,则额外的开销加在一起可能会花费很长的时间。
解决方案很简单:只在一个事务中执行所有操作。
我怀疑你会遇到任何这样的性能问题。试着做这样的事情:
final SQLiteDatabase database = this.openHelper.getWritableDatabase();
try {
// Begin the transaction
database.beginTransaction();
for(Entity entities : viewModels) {
// Perform your updates here
ContentValues contentValues = EntityConverter.toContentValues(entity);
database.update(table, contentValues, "_id = ?", entity.getId());
}
// When everything worked set the transaction successful.
// If you don't call this method the transaction will be rolled back.
database.setTransactionSuccessful();
} finally {
// End the transaction
database.endTransaction();
}除了非常大的性能提升,还有其他优势。假设您想更新数据库中的2000行,在一个事务中执行所有操作,但在应用程序崩溃的过程中执行一半。如果您已经在自己的事务中执行了每个命令,那么现在可能会有一个很大的问题。一半的数据被提交,另一半被丢失。您的数据库可能已损坏或处于不希望的状态。但是,如果您在一个事务中完成所有的操作,您将保存它,因为事务可以完全成功,也可以不成功。如果在执行事务时出现错误或异常或任何事情,则不会对数据库进行任何更改。只要您使用的事务(如我前面所解释的),您就可以确保事务中的每个命令都是成功执行的,或者根本没有执行任何命令。
https://stackoverflow.com/questions/24739278
复制相似问题