You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不加载全部数据到内存的情况下遍历SqlDelight查询结果?

SqlDelight 大表逐行查询方案探讨

我观察到SqlDelight的Query对象没有可替代executeAsList()的逐行查询方法——executeAsList()会一次性加载全部数据,无法直接用于处理大表(内存无法承载全量数据)。

现有两种接近需求但存在缺陷的方案:

  • 使用execute()函数:允许逐行处理结果,但会丢失类型安全性,需要手动处理原生SQLite列的类型转换:
val a = mDb.testQueries.selectAll().execute { cursor ->
    while (cursor.next().value) {
        println("cursor $cursor")
    }
    QueryResult.Unit
}
  • 传入映射器构造查询:能恢复类型安全性,但必须调用executeAsList()返回全量结果列表,依然会因加载整张表数据而浪费内存:
mDb.testQueries.selectAll { id, foo, bar, timestamp ->
    println("Running on id $id, timestamp $timestamp")
}.executeAsList()

除了自行编写分页代码外,真的没有其他查询大表的方法吗?


更新:可行的扩展函数方案

基于Stack Overflow回答实现的扩展函数,既支持逐行处理,又保留了类型安全性:

fun <RowType : Any> Query<RowType>.iterate(block: (RowType) -> Unit) {
    execute { cursor ->
        while (cursor.next().value) {
            block(mapper(cursor))
        }
        QueryResult.Unit
    }
}
// 使用示例
mDb.testQueries.selectAll().iterate { id, foo, bar, timestamp ->
    // 此处编写逐行处理逻辑
}

内容的提问来源于stack exchange,提问作者Grzegorz Adam Hankiewicz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 04:56:21