假设我有一个包含大量项目的网格视图。网格视图中的项目可以通过拖动和拖放来进行洗牌。下降。一旦shuffle完成,我想将项目的顺序存储在Database中,以便稍后我可以读取它以恢复相同的顺序。
我的思维过程是为每个项目分配订单,当洗牌完成后,我计划用新订单更新数据库中的所有相关记录。但是运行许多更新查询似乎是如此昂贵的任务。请建议我使用优化技术来完成任务。提前谢谢。
答案 0 :(得分:3)
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行,您可以在一个事务中执行所有操作,但是在应用程序崩溃的中途。如果您在自己的事务中执行了每个命令,那么现在可能会遇到一个大问题。一半的数据被提交,另一半被丢失。您的数据库可能已损坏或处于不良状态。但是,如果您在一个单一事务中执行所有操作,则可以保存,因为事务可以完全成功。如果在执行事务时出现错误或异常或任何内容,则不会对数据库进行任何更改。只要您使用上面解释过的事务,就可以确保事务中的每个命令都成功执行或者根本不执行任何命令。