2011-07-15 64 views
6

我正在研究我的一个基于核心数据的应用程序的搜索功能,并试图收集每个人关于搜索优化的提示,以尽可能快地获得它。搜索需要足够快,以便能够为20,000多个对象的数据库提供近乎即时的结果。核心数据搜索优化

什么我迄今所做的(只要优化云)

  • 实现在WWDC 2010大会137所示的技术,创建关键字实体,创建从我的主要目的实体一对多的关系到它。关键字实体的name属性索引,并在主要实体裂开相关的字符串和规范他们的初始导入过程中创建的关键字(剥去外壳和变音符号)
  • 使用>=<二进制比较,而不是BEGINSWITH等我的谓词格式为:

SUBQUERY(keywords, $keyword, ($keyword.name >= $LB) AND ($keyword.name < $UB))[email protected] != 0

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

现在,我使用大约20的获取批量大小执行一次提取(当用户输入第一个字母时),然后在继续输入时使用NSArray的-filteredArrayUsingPredicate方法缩小搜索结果范围。我还预取了keywords关系,因为这用于过滤。显然,占用最多时间的部分是最初的抓取。在约15,000个物体的图书馆中,有1-2秒的明显延迟。时间分析表明,它确实是获取引起该延迟:

http://cl.ly/3a1b2022452M2V323f2H

一件事值得一提的是这就是我要的结果取多个实体。所有实体都具有ranking属性,但我无法一次获取多个属性,因此我不得不分别获取它们,将它们合并为一个数组,然后通过-sortedArrayUsingDescriptors手动排序。

任何提示如何加快这一点将不胜感激。

编辑:基于@ImHuntingWabbits的建议:

加入KeywordFirstChar实体后,我的数据模型(简体)应该是这样的:

new model

现在,问题是如何为Car实体提供基于KeywordFirstChar提取的谓词?我能想到的唯一的事情是这样的:

SUBQUERY(keywords, $keyword, $keyword.firstChar.char == %@)其中%@是搜索的性格,但我不知道怎么这将是更有效的考虑,它仍具有枚举keywords,除非我误解了这些建议。

+0

您不是遍历每个关键字,生成的SQL应该只检查keywordFirstChar表中的char值。 Car实体的结果集将通过从KeywordFirstChar到Keyword到Car的连接来获取。 – ImHuntingWabbits

+0

是的,明白了。它现在运行得更好,方式更快。谢谢 – indragie

回答

4

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

您仍在扫描第一个字符命中的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或一些其他财产)。

+0

感谢您的回复,该解决方案非常有意义。这就是说,我不完全确定细节。例如,我的谓词看起来像获取“KeywordFirstChar”实体,以及如何从该提取中检索我的主对象(连接到关键字的那些对象)? – indragie

+0

我已经编辑过我的帖子以包含更多详细信息(根据您的其他建议),因为我认为我可能会误解某些内容, – indragie