如何提高核心数据的性能?

时间:2010-08-15 20:46:39

标签: iphone core-data performance nspredicate

我的应用有一个UISearchBar,允许用户输入搜索关键字。每次击键都会执行核心数据查询,以便在搜索栏更改时将结果显示为文本。

问题是搜索栏击键相当糟糕......当然是因为提取速度慢。任何想法如何提高性能?

我的核心数据由sqlite数据存储支持,其中包含1000个对象。

// searchKeyword is the string appears in UISearchBar
// Both title and author may contain several words so I can't use BEGINSWITH
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"(author CONTAINS[c] %@) OR (title CONTAINS[c] %@)", searchKeyword, searchKeyword];

NSEntityDescription* entity = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:managedObjectContext];

NSFetchRequest* request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
[request setPredicate:predicate];
[request setFetchLimit:10];

NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES];
NSArray* sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];

[sortDescriptor release];
[sortDescriptors release];

execute request and fetch the results
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                managedObjectContext:managedObjectContext
                                sectionNameKeyPath:nil
                                cacheName:nil];
NSError* error = nil;
BOOL success = [fetchedResultsController performFetch:&error];
[request release];

5 个答案:

答案 0 :(得分:18)

使用CONTAINS减慢速度。您需要做的是创建一个名为searchWords(或其他)的新表,并在该商店中标题中的所有单词,小写并删除重音。这些关系将它们链接回原始对象。确保单词字段已编入索引。

在此表上执行查询,但不要使用CONTAINS或BEGINSWITH,而是执行类似

的操作

word> “term”AND word< “鸥”

请注意,其中的第一个字符串是搜索字词,第二个字符串是最后一个字符递增的搜索字词。这允许Core Data使用SQL索引来执行搜索。

Apple有一个Core Data WWDC会话,解释了这一点,包括示例代码。示例代码包含一个类,用于处理规范化字符串(即删除大小写),并以unicode感知方式递增单词的最后一个字符。

答案 1 :(得分:13)

虽然Amoyra的建议合理,但您也有设计问题。

只有输入搜索字段的第一个字母才能永远点击磁盘。在第一个字母之后,你应该只是改进已经在内存中的搜索结果。

您应该使用您已有的谓词过滤内存中的数组(来自第一个字母搜索),并避免执行获取请求,因为它是不必要的。

此外,如果您要搜索已经在内存中的数据(例如生活在NSFetchedResultsController中),那么您的整个搜索应该只搜索内存中的对象。走出磁盘是不必要的,非常浪费。

答案 2 :(得分:4)

虽然它不会加快查询速度,但将查找放入后台线程会阻止按键停滞。

答案 3 :(得分:2)

您可以逐步创建trie,以便为过去的查询创建索引(结果集由叶节点指向)。但它不会增加单个查询的性能。你也可以调整击键系统,不要在每次击键后进行提取,但只有在击键之后才能在识别出另一次击键之前经过一段时间间隔(作为一个阈值)

答案 4 :(得分:-1)

启动应用程序时,请构建完整的trie,并在编辑时进行调整。不要使用那个愚蠢的谓词。你只需要提取1000条记录,所以不应该花时间。

相关问题