我使用 Room 作为 SQLite 的抽象层。看完这篇page我发现我们可以同时插入多个对象。目前我使用 For 循环来插入对象,即在每个 For 循环迭代中插入一个对象。我目前知道的两种插入方式是:
使用 For 循环并一次插入一个对象
@Insert(onConflict = OnConflictStrategy.REPLACE) public void addActivity(Person person);
插入数组或对象列表。
@Insert(onConflict = OnConflictStrategy.REPLACE) public void insertUsers(Person ... people);
当我编写对象插入代码时,我不知道第二种插入方式。现在我想知道这两种方式之间的速度是否有明显差异,以便我可以更改我的代码以提高我的应用程序的性能。
最佳答案
按照 OP 在他们的问题的评论中的要求,这里是(为了清楚起见,作为答案)我做了什么来检查性能:
之前,一个一个插入对象:
@Dao
abstract class MyDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun insert(items: MyObject): Long
// ...
}
同步代码:
val response = backend.downloadItems() // download from server
val items = response.getData() // this is a List<MyObject>
if (items != null) {
for (i in items) {
myDao.persist(s)
}
}
这在华为 P10+ 上花了一分钟。
我将其更改为:
@Dao
abstract class MyDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun insert(items: Iterable<MyObject>)
// ...
}
同步代码:
val response = backend.downloadItems() // download from server
val items = response.getData() // this is a List<MyObject>
response.getData()?.let { myDao.insert(it) }
这只用了不到一秒钟。
这里的重点是专门使用 Iterable<>
DAO 版本 @Insert
方法,如@iDemigod 所述,使用 Iterable<>
EntityInsertionAdapter
的版本.
所述函数的主体在@iDemigod 的回答中,并且它对所有插入使用一个准备好的语句。
将 SQL 解析成一条语句是昂贵的,并且使用一条语句会为整个插入批处理创建一个事务,这有助于解决其他问题(我在数据库上有一个可观察的 LiveData<>
,在整个过程中被通知了 12k 次插入...性能糟糕)。
关于安卓房间。哪种插入方法会更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50384683/