Android: Why is Room so slow?(Android:为什么Room这么慢?)
问题描述
我正在使用Room在Kotlin中编写一个简单的数据库过程,我无法解释为什么该过程如此缓慢,主要是在Android Studio模拟器上。
我正在处理的表格是:
@Entity(tableName = "folders_items_table", indices = arrayOf(Index(value = ["folder_name"]), Index(value = ["item_id"])))
data class FoldersItems(
@PrimaryKey(autoGenerate = true)
var uid: Long = 0L,
@ColumnInfo(name = "folder_name")
var folder_name: String = "",
@ColumnInfo(name = "item_id")
var item_id: String = ""
)
我只是想这样做:检查组合文件夹/项目是否已经存在,插入一个新记录。如果不是,那就忽略它。在模拟器上,插入100条记录最多需要7-8秒。在真正的设备上,它的速度要快得多,但仍然需要大约3-4秒,这对于只有100条记录的人来说是不可接受的。看起来插入查询特别慢。
下面是实现我刚才描述的过程(在协程中):
val vsmFoldersItems = FoldersItems()
items.forEach{
val itmCk = database.checkFolderItem(item.folder_name, it)
if (itmCk == 0L) {
val newFolderItemHere = vsmFoldersItems.copy(
folder_name = item.folder_name,
item_id = it
)
database.insertFolderItems(newFolderItemHere)
}
}
变量&Quot;Items&Quot;是字符串数组。
以下是上述调用函数的DAO定义:
@Query("SELECT uid FROM folders_items_table WHERE folder_name = :folder AND item_id = :item")
fun checkFolderItem(folder: String, item: String): Long
@Insert
suspend fun insertFolderItems(item: FoldersItems)
推荐答案
将循环放在单个事务中应可显著减少所用时间。
原因是每个事务(默认情况下,对数据库进行更改的每个SQL语句)都将导致磁盘写入。这就是您的循环的100次磁盘写入。
如果在循环之前开始事务,然后在循环完成时将事务设置为成功,然后结束事务,则需要进行一次磁盘写入。
我不确定的是,在使用挂起的函数(对Kotlin不是很熟悉)时,如何准确地执行此操作。
因此,我建议删除挂起或在循环中使用另一个DAO。
然后像这样:-
val vsmFoldersItems = FoldersItems()
your_RoomDatabase.beginTransaction()
items.forEach{
val itmCk = database.checkFolderItem(item.folder_name, it)
if (itmCk == 0L) {
val newFolderItemHere = vsmFoldersItems.copy(
folder_name = item.folder_name,
item_id = it
)
database.insertFolderItems(newFolderItemHere)
}
}
your_RoomDatabase.setTransactionSuccessful() //<<<<<<< IF NOT set then ALL updates will be rolled back
your_RoomDatabase.endTransaction()
您可以参考:-
- https://developer.android.com/reference/androidx/room/RoomDatabase
您可能需要特别参考runInTransaction
这篇关于Android:为什么Room这么慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Android:为什么Room这么慢?
基础教程推荐
- my.cnf 文件在 macOS 上的位置 2021-01-01
- SSIS:在数据流中使用 System::TaskName 2021-01-01
- Sql*plus 总是返回退出代码 0? 2021-01-01
- 如何将参数传递给使用 sqlcmd 调用的 SQL Server 脚本? 2021-01-01
- (+) 在 Oracle SQL 中有什么作用? 2021-01-01
- 哪个是 Rails 应用程序的最佳数据库? 2022-01-01
- 与不使用派生表的查询相比,使用派生表的查询 2021-01-01
- 如何在没有密码提示的情况下执行 mysqldump? 2021-01-01
- 为 SQL Server 设置 Maven 依赖项 2021-01-01
- 替换存储在 SQL Server 数据库列中的 XML 中的节点名 2021-01-01