Android 与Room相比,Sql的性能较慢

Android 与Room相比,Sql的性能较慢,android,android-room,kotlin-multiplatform,sqldelight,Android,Android Room,Kotlin Multiplatform,Sqldelight,我们希望将我们的应用程序从Room迁移到SQLDelight,以便在iOS上重用它(这是一个多平台项目)。 然而,我注意到SQLDelight比Room慢得多。对于某些查询,速度大约慢10倍。 我使用insert语句进行了一些深入测试,在Room中平均需要5毫秒,在SQLDelight中平均需要25毫秒。我检查(并调整)了查询,使它们完全相同 我还检查了一些Pragma,发现SQLDelight使用Pragma SYNCHRONOUS=1(FULL),而Room使用2(NORMAL),SQLDe

我们希望将我们的应用程序从Room迁移到SQLDelight,以便在iOS上重用它(这是一个多平台项目)。 然而,我注意到SQLDelight比Room慢得多。对于某些查询,速度大约慢10倍。 我使用insert语句进行了一些深入测试,在Room中平均需要5毫秒,在SQLDelight中平均需要25毫秒。我检查(并调整)了查询,使它们完全相同

我还检查了一些Pragma,发现SQLDelight使用Pragma SYNCHRONOUS=1(FULL),而Room使用2(NORMAL),SQLDelight使用JOURNAL\u MODE=TRUNCATE,而Room使用WAL。我在SQLDelight设置中更改了这些设置,使其与Room相同,性能有所提高,但对于上面描述的测试,仍然是~20ms


有人知道是什么导致了这种差异吗?非常感谢您的帮助。

性能下降的原因似乎是日志模式和同步设置。我以前没有意识到这一点,因为我的改变没有按预期的方式进行

因此,我目前的答案是将日志模式设置为WAL,将同步设置为2,这是Room的默认设置。我只能通过在DriverFactory中使用以下代码来完成它,如果有人有更干净的解决方案,我很高兴看到它

actual class DriverFactory(private val context: Context) {
    actual fun createDriver(): SqlDriver {
        return AndroidSqliteDriver(
            schema = Database.Schema,
            context = context,
            name = "Database.db",
            callback = object : AndroidSqliteDriver.Callback(Database.Schema) {
                override fun onConfigure(db: SupportSQLiteDatabase) {
                    super.onConfigure(db)
                    setPragma(db, "JOURNAL_MODE = WAL")
                    setPragma(db, "SYNCHRONOUS = 2")
                }

                private fun setPragma( db: SupportSQLiteDatabase, pragma: String) {
                    val cursor = db.query("PRAGMA $pragma")
                    cursor.moveToFirst()
                    cursor.close()
                }
            }
        )
    }
}

性能下降的原因似乎是日志模式和同步设置。我以前没有意识到这一点,因为我的改变没有按预期的方式进行

因此,我目前的答案是将日志模式设置为WAL,将同步设置为2,这是Room的默认设置。我只能通过在DriverFactory中使用以下代码来完成它,如果有人有更干净的解决方案,我很高兴看到它

actual class DriverFactory(private val context: Context) {
    actual fun createDriver(): SqlDriver {
        return AndroidSqliteDriver(
            schema = Database.Schema,
            context = context,
            name = "Database.db",
            callback = object : AndroidSqliteDriver.Callback(Database.Schema) {
                override fun onConfigure(db: SupportSQLiteDatabase) {
                    super.onConfigure(db)
                    setPragma(db, "JOURNAL_MODE = WAL")
                    setPragma(db, "SYNCHRONOUS = 2")
                }

                private fun setPragma( db: SupportSQLiteDatabase, pragma: String) {
                    val cursor = db.query("PRAGMA $pragma")
                    cursor.moveToFirst()
                    cursor.close()
                }
            }
        )
    }
}

你能发布你的代码吗?基准测试在很大程度上取决于所有的细节。很抱歉,我不能发布它,因为它是为客户准备的。但我现在才发现,这似乎确实是一种日志模式。在驱动程序onOpen回调中将其设置为WAL不起作用,可能稍后会被覆盖…我不知道android驱动程序的即时情况,但在iOS上,您非常需要使用配置设置日志模式,而不是直接设置日志模式,因为它需要按特定顺序进行。好的,谢谢!我试图找出安卓的合适位置。似乎它在onconfig中也不起作用,它总是重置为truncate。如果我自己搞不懂,我会更新这个问题。你能发布你的代码吗?基准测试在很大程度上取决于所有的细节。很抱歉,我不能发布它,因为它是为客户准备的。但我现在才发现,这似乎确实是一种日志模式。在驱动程序onOpen回调中将其设置为WAL不起作用,可能稍后会被覆盖…我不知道android驱动程序的即时情况,但在iOS上,您非常需要使用配置设置日志模式,而不是直接设置日志模式,因为它需要按特定顺序进行。好的,谢谢!我试图找出安卓的合适位置。似乎它在onconfig中也不起作用,它总是重置为truncate。如果我自己搞不清楚,我会更新这个问题。iOS默认值是WAL,仅供参考。iOS默认值是WAL,仅供参考。