【问题标题】:Core Data search optimization核心数据搜索优化
【发布时间】:2011-10-05 20:59:42
【问题描述】:

我正在我的一个基于 Core Data 的应用程序中开发搜索功能,我正在尝试收集每个人关于搜索优化的提示,以尽可能快地获得它。搜索需要足够快,才能为包含 20,000 多个对象的数据库提供近乎即时的结果。

到目前为止我所做的(就优化而言)

  • 实现了 WWDC 2010 会话 137 中显示的技术,创建了一个关键字实体并创建了从我的主要对象实体到它的一对多关系。关键字实体的name 属性已编入索引,并且在初始导入过程中通过拆分主要实体中的相关字符串并对其进行规范化(去除大小写和变音符号)来创建关键字
  • 使用>=< 二进制比较器代替BEGINSWITH 等。我的谓词格式是:

SUBQUERY(keywords, $keyword, ($keyword.name >= $LB) AND ($keyword.name < $UB)).@count != 0

其中$LB 是字符串的下限,$UB 是上限。我使用这种格式和搜索词数组创建了一个复合 AND 谓词。

现在,我正在执行一次提取(当用户键入第一个字母时),使用大约 20 的提取批量大小,然后在他们继续输入时使用 NSArray 的 -filteredArrayUsingPredicate 方法缩小搜索结果。我还预取了keywords 关系,因为它用于过滤。显然,占用时间最多的部分是初始提取。在大约 15,000 个对象的库中,有大约 1-2 秒的明显延迟。时间分析表明确实是 fetch 导致了延迟:

http://cl.ly/3a1b2022452M2V323f2H

另一件值得注意的事情是我必须为结果获取多个实体。所有实体都有一个ranking 属性,但我一次无法获取多个实体,因此我不得不分别获取它们,将它们组合成一个数组,然后通过-sortedArrayUsingDescriptors 手动排序。

任何关于如何加快速度的提示将不胜感激。

编辑:基于@ImHuntingWabbits 的建议:

添加KeywordFirstChar 实体后,我的数据模型(简化)如下所示:

现在,问题是如何为基于KeywordFirstChar 获取的Car 实体编写谓词?我唯一能想到的就是:

SUBQUERY(keywords, $keyword, $keyword.firstChar.char == %@) 其中%@ 是要搜索的字符,但考虑到它仍然必须枚举keywords,我不知道这将如何更有效,除非我误解了这些建议。

【问题讨论】:

  • 您没有对每个关键字进行迭代,生成的 SQL 应该只检查 keywordFirstChar 表中的 char 值。 Car 实体的结果集将通过从 KeywordFirstChar 到 Keyword 到 Car 的连接来获取。
  • 是的,知道了。它现在工作得更好,速度更快。谢谢

标签: objective-c performance macos core-data nsfetchrequest


【解决方案1】:

您的查询经过高度优化,我认为您已经采取了很多步骤。至于第一个字符,你做错了。

您仍在扫描 15k 条记录以查找第一个字符命中,并且可能匹配大量记录。

您可以通过索引关键字索引来进一步优化它,创建两个新实体:

  • KeywordFirstChar
  • KeywordFirstTwoChars

两者都与它们指向的关键字存在一对多关系。

if (searchPredicate.length == 1) {
    //search on KeywordFirstChar
} else if (searchPredicate.length == 2) {
    //search on KeywordFirstTwoChars
} else {
    //search on keyword
}

这样,您的表扫描将分别超过最多 26 行和 676 行,这应该是微不足道的。只需确保关系位于获取请求的预取关系键路径中,这样您就可以确实从磁盘上获取数据。

编辑(对象检索):

您可以按照关系键路径,所以它会是这样的:

 [fetchRequest setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObject:@"keyword.sourceObject"]];

其中关键字是与关键字实体的关系,sourceObject 是您最终要检索的对象。

编辑(谓词):

谓词本质上是相同的,只是更改名称以匹配新实体(名称可能不会映射到名称,而是 firstChar 或其他一些属性)。

【讨论】:

  • 感谢您的回复,该解决方案很有意义。也就是说,我不完全确定细节。例如,我的谓词在获取“KeywordFirstChar”实体时会是什么样子,我将如何从该获取中检索我的主要对象(连接到关键字的对象)?
  • 我已经编辑了我的帖子以包含更多详细信息(基于您的其他建议),因为我认为我可能会误解某些内容,
猜你喜欢
  • 1970-01-01
  • 2012-02-16
  • 1970-01-01
  • 2014-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多