【问题标题】:How can I quickly query SQLite given a list of rowids?如何在给定 rowid 列表的情况下快速查询 SQLite?
【发布时间】:2018-11-22 21:31:05
【问题描述】:

如何快速查询与 rowid 列表匹配的记录?我的 iOS 应用中有一个查询,如下所示:

SELECT rowid, category_id
FROM items
WHERE rowid in (2, 4, 89, 4243, 44, 555, ...)

rowid 列表可能有点长 - 几百个项目就是一个典型示例。

奇怪的是,这个查询需要几秒钟才能运行——在某些情况下可能长达 12 秒。无论是在 SQLite shell 中运行还是在我的应用程序中运行,都会很慢。

但是,如果我将这个查询替换为:

SELECT rowid, category_id
FROM items

所以我检索表中的每一项(在我的测试用例中,大约 1000 行),只是让我的应用程序忽略它不需要的 rowid,查询仅在几百毫秒内执行。它还在 SQLite shell 中快速响应。

这里发生了什么? rowid 是一个主键,所以这应该是一个快速的索引查找。有没有更快的方法来运行这样的查询?我会认为是解析查询字符串会有所不同,但分析显示几乎所有时间都花在了sqlite3_step

【问题讨论】:

  • 嗯,与其他解决方案相比,WHERE rowid in(.....) 的性能应该相当不错。该查询之外是否有任何内容可能会减慢您的查询响应速度?
  • WHERE...IN 不适用于大型列表,因为 在内部 它将被视为无法优化的大型 OR 列表好吧。但是您可以尝试这种方法:xaprb.com/blog/2006/06/28/why-large-in-clauses-are-problematic
  • @Martin 我不这么认为,因为我在 SQLite shell 中看到了问题
  • @AndreasOetjen 所以基本上,使用临时表?
  • @Bill 是的,可以加入。根据您的用例 - 也许您的 id 列表不会经常更改 - 持久的 id 表也可能是一个很好的解决方案。

标签: ios sql sqlite


【解决方案1】:

不带 where 子句的 SQL 查询总是比带 where 类的查询快。您提到 RowID 是表中的主键(因此,默认创建它的集群索引)。

请尝试将 'where...In' 替换为 'where...between' 或 where...rowId>X 和 RowId

其他解决方案是将可比较的行 ID 列表移动到临时表/视图并执行内部连接以更快地获得结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多