本文介紹了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這么慢?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,