【发布时间】: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