【发布时间】:2021-08-07 01:17:55
【问题描述】:
我正在使用 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)
}
}
变量“items”是一个字符串数组。
这是上述函数的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)
【问题讨论】:
-
我认为您应该只在值列中使用create an unique index,然后只运行一批插入,而不是循环运行检查查询,然后对每个项目进行插入查询。
-
谢谢@Pawel,我试过了,但事实是,由于这个过程是异步调用的,一旦插入查询尝试存储一个已经存在的值,它就会产生异常并且循环是破碎的。所以,我必须坚持我的简单查询检查......无论如何,谢谢!
-
它有什么异常?如果我对“批量插入”不清楚,我的意思是修改(或添加新的)DAO 方法
insertFolderItems以使用OnConflictStrategy.IGNORE消耗整个列表,并且您不会有任何循环。 -
好点@Pawel,我没想到。我明天试试,然后报告。再次感谢您。
-
是的@Pawel,解决了它!再次感谢!
标签: sqlite kotlin android-room dao