【问题标题】:sqlite Indexing Performance Advicesqlite 索引性能建议
【发布时间】:2010-12-24 04:22:20
【问题描述】:

我的 iPhone 应用程序中有一个 sqlite 数据库,我通过 Core Data 框架访问它。我正在使用 NSPredicates 来查询数据库。

我正在构建一个搜索功能,该功能需要搜索六个不同的包含文本的 varchar 字段。目前,它非常慢,我需要提高性能,可能在 sqlite 数据库中。最好在所有这些列上创建索引吗?或者构建一个自定义索引表,将这六列扩展为多行,每行包含一个单词和它匹配的 ID,会更好吗?还有其他建议吗?

【问题讨论】:

  • 您的问题令人困惑。如果你使用 Core Data,你永远不会直接访问 SQLite 数据库。 “varchar”和“table”之类的词在 Core Data 中没有意义。您应该修改您的问题,以澄清您实际上是在使用 Core Data 还是只是在使用普通的旧 SQLite 数据库。
  • 感谢您的评论亚历克斯,我已经更新了我的问题。我从不直接在我的代码中访问 sqlite 数据库,但我可以在 xcode 的背后。例如,我使用 sqlite3 命令行程序为我的数据库植入数据。

标签: iphone sqlite search indexing


【解决方案1】:

来自Core Data Programming Guide

如何使用谓词可以 显着影响性能 您的应用程序。如果取 request 需要一个复合谓词, 你可以让获取更有效率 通过确保最严格的 谓词是第一个,特别是如果 谓词涉及文本匹配 (包含、endWith、like 和 匹配)因为正确的 Unicode 搜索很慢。如果谓词 结合文字和非文字 比较的话,很可能是 更有效地指定 首先是非文本谓词,对于 示例(薪水 > 5000000)和 (lastName LIKE 'Quincey') 更好 比 (lastName LIKE 'Quincey') AND (工资> 5000000)。

如果有一种方法可以重新排序查询,使最简单的逻辑在左侧,最复杂的在右侧,这有助于提高搜索性能。正如里昂所建议的那样,搜索 Unicode 文本非常昂贵,因此 Apple 建议搜索去除 Unicode 字符和常用短语(如 a、and 和 the)的派生值。

【讨论】:

  • 我可能能够提取出常用词,但可能不会。我认为用户永远不会输入数字。我的查询字符串效率极低,使用如下内容: ((name contains[cd] %@) OR (color contains[cd] %@) OR (...)) AND ((name contains[cd] %@) OR (color contains[cd] %@) OR (...)) AND (...) 大量的 OR。如果 sqlite 和我用过的其他数据库一样,那是一种非常慢的搜索方式。老实说,也许解决方案比所有这些都简单。也许我只需要在用户点击“搜索”而不是每次输入字母时才回复?
  • 您仍然可以通过搜索去除了 unicode 字符的派生属性而侥幸成功。仅此一项就可以显着提升性能。
【解决方案2】:

如果您想要的基本上是对您的 sqlite 数据库进行全文索引,那么您可能想要使用 sqlite 的 ft3 模块,因为这正是它所提供的: http://www.sqlite.org/cvstrac/wiki?p=FtsUsage http://dotnetperls.com/sqlite-fts3

【讨论】:

  • CoreData 支持 FTS3 吗?这可能就是为什么我应该在这篇文章的标题中留下 CoreData。不过我会调查的。
【解决方案3】:

我假设这些列存储文本。问题是有多少文本以及访问该模型的频率。如果是大量文本,我会创建其他属性来保存文本,去除常用词和 Unicode 文本。唯一的缺点是您最终需要维护额外的属性。您可以进行任何索引以提高这些列的性能。

【讨论】:

  • 是的,他们确实存储文本...我已经更新了我的问题以反映这一点。我有大约 500 行,六列中的每一列平均有五个单词。所以总的来说,我搜索了大约 3000 个单词。我只是不清楚索引如何在 sqlite 中工作。我需要仔细阅读。
  • @mswebersd:如果您的数据库只有 500 行,我很好奇您调用它的速度非常慢会发生什么。不管它是否被索引,对该大小的表的查询应该接近瞬时。你到底在执行什么 SQL?
  • ((name contains[cd] %@) OR (color contains[cd] %@) OR (...)) AND ((name contains[cd] %@) OR (color contains [cd] %@) OR (...)) AND (...) 大量 OR 并包含 [cd]。
  • 它在表格上使用 UISearchBar,只要用户输入字母且字符串长度 > 0,搜索就会运行。
  • 哦,还有一件事......我忘了提到每个 OR 短语都是一个单词(我在空格字符上分开)。所以 AND 连接了多个单词。
【解决方案4】:

您可以采取一些措施来提高在 sqlite 数据库中搜索文本的性能。尽管 Core Data 将您从底层存储中抽象出来,但是当您的存储使用 sqlite 支持时,了解正在发生的事情可能会很好。

如果我们假设您正在对这些字段进行子字符串搜索,那么您可以采取一些措施来提高搜索性能。 Apple 推荐使用派生属性。这相当于在您的模型中维护用于搜索的属性的标准化版本。派生属性应该以可以被索引的方式完成。然后,您可以使用二元运算符 > 根据此派生属性表达您的搜索。

我发现这样做可以将我们的搜索时间从大约 1 秒减少到 100 毫秒以下。

为了清楚起见,我建议查看 ADC 示例 http://developer.apple.com/mac/library/samplecode/DerivedProperty/

【讨论】:

  • 今晚我会看看这个例子。我还需要阅读派生属性。感谢您的提示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多