2011-04-21 45 views
3

我一直想看看有什么办法可以改善以下谓词的性能:核心数据:子查询性能问题

[NSPredicate predicateWithFormat:@"A=%@ and SUBQUERY($self.words,$k,$k.keyword IN %@)[email protected]==%d", 
    <value for A>, 
    keywordList, 
    [keywordList count]]; 

我试图做的是返回所有A的关键字记录全部包含在提供的数组(关键字列表)中。我有一个大约2000条记录的小型数据库。但是,每个实体的关键字范围从40到300个关键字。关键字表示为从A到称为关键字的实体的多对多关系。上面的查询工作,但需要大约7秒在我的iPhone4上运行。我想看看我能做些什么来缩小到亚秒级的反应。

感谢, 迈克尔

+2

如果您只是查询给定A的关键字,那么性能如何?我的意思是,你可以重写谓词来做子查询作为主查询。 – 2011-04-22 00:20:03

回答

0

我想你向后接近的问题。如果您有关键字,则应该搜索Keyword对象,然后走他们的A关系以查找相关的A对象。 然后检查关系集中的重叠。

因此,像:

NSFetchRequest *fetch=//...set up fetch 
[fetch setEntity:Keyword_entity]; 
NSPredicate *p=[NSPredicate predicateWithFormat:@"keyword IN %@",keywords]; 
[fetch setPredicate:p]; 
NSArray *fetchedObj=//... execute fetch 

NSMutableSet *inCommon=[NSMutableSet setWithCapacity:[fetchedObjs count]]; 
for (NSManagedObject *mo in fetchedObjs){ 
    if ([inCommon count]==0){ 
    [inCommon addObjects:[mo valueForKey:@"aRelationshipName"]]; 
    }else{ 
    [inCommon intersectSet:[mo valueForKey:@"aRelationshipName"]]; 
    } 
} 

... inCommon随后将含有一组共享所有关键字的所有独特 A对象。
更新:

从OP作者:

这并不完全解决问题 作为来自fetchedObjs的 路口回的结果是不正确的 。它并不保证所有 'A'对象包含提供的所有关键字 。

好的,让我们再试一次。假设你有一个看起来像这样的数据模型:

A { 
    keywords<<-->>Keyword.as 
} 

Keyword{ 
    keyword:string 
    as<<-->>A.keywords 
} 

那么这样的事情应该工作:

NSFetchRequest *keyWordFetch=//...set up fetch 
[keyWordFetch setEntity:Keyword_entity]; 
NSPredicate *p=[NSPredicate predicateWithFormat:@"keyword IN %@",keywords]; 
[keyWordFetch setPredicate:p]; 
NSArray *fetchedKeywords=//... execute keyWordFetch 


NSFetchRequest *entityAFetch=//...set up fetch 
[entityAFetch setEntity:A_entity]; 
NSPredicate *pred=[NSPredicate predicateWithFormat:@"ALL keywords IN %@", fetchedKeywords); 
[entityAFetch setPredicate:pred]; 
NSArray *fetchedAs=//... execute fetch 
+0

查看我的更新回答上面 – TechZen 2011-04-23 14:02:46

+0

谢谢。你最初的评论让我思考。我最终重塑了我的设计。我的搜索现在是一个多通道搜索。第一个扫描一个标准化的关键字表,并生成一个匹配'A'对象的记录标识集。第二遍从第一个请求中查询集合中具有ID的所有'A'对象。 – 2011-04-24 09:39:11

+0

搜索现在在我的iPhone4上进行亚秒。谢谢您的帮助!我最终删除了A和关键字之间的关系。这也为我解决了另一个问题,那就是加载。无需对关系进行建模,加载时间显着缩短。 – 2011-04-24 10:17:28

0

这并不完全解决问题,因为从交叉回来的结果fetchedObjs不正确。它并不保证所有'A'对象都包含所有提供的关键字。事实上,返回的是一个空的列表,整个过程实际上需要更长的时间。

我的模型或以前的答案必定有问题。我没有得到我期待的结果。返回'A'列表的另一种方法是返回'A'的ManagedObjectID列表。 [mo valueForKey:(NSString *)]返回关系的对象。

注:我原本以匿名的方式发布这个问题,我以为我登录了,所以我似乎无法评论任何人的答案。

+0

我将您的其​​他帐户合并到了您的其他帐户中,以便您可以编辑问题并发表评论。完成后请删除此答案。谢谢,欢迎来到Stack Overflow。 – 2011-04-23 12:30:56