Ios NSSortDescriptor的性能如何?

Ios NSSortDescriptor的性能如何?,ios,performance,core-data,nsfetchedresultscontroller,nssortdescriptor,Ios,Performance,Core Data,Nsfetchedresultscontroller,Nssortdescriptor,我有一个SQLite支持的数据库,大约有4000行,连接到核心数据。该模型是一个简单的概述->详细模型。每个概述(带有标题和副标题)都与包含详细信息的详细信息相关。为了查看这些数据,我使用NSFetchedRequestController实现了UITableView NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"registered_name" ascending:YES]; NSArray

我有一个SQLite支持的数据库,大约有4000行,连接到核心数据。该模型是一个简单的概述->详细模型。每个概述(带有标题和副标题)都与包含详细信息的详细信息相关。为了查看这些数据,我使用NSFetchedRequestController实现了UITableView

NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"registered_name" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sort];
        
NSPredicate *filterPredicate = nil;
NSString *sectionName = nil;
NSString *cacheName = nil;
    
NSFetchedResultsController *aFetchedResultsController = nil;
aFetchedResultsController.delegate = self;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

[fetchRequest setFetchBatchSize:20];
[fetchRequest setSortDescriptors:sortDescriptors];
    
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Info" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
    
[fetchRequest setPredicate:filterPredicate];
aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:sectionName cacheName:cacheName];

NSError *error = nil;
if (![aFetchedResultsController performFetch:&error]) 
  NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
  abort();
}

[fetchRequest release];
[sort release];
return aFetchedResultsController;`
我已经实现了所有的功能,它可以正常工作,但是工作很慢。我特别关注应用程序的发布

这是在启动时减慢速度的查询(XCode中的SQL调试标志):

这在执行performFetch后立即发生。为什么核心数据需要获取并排序数据库中的所有4302行?如果我将setLimit设置为一个较小的值,比如20,当然,所有操作都非常快,但我只显示20个结果。另一方面,我现在有了setBatchSize,它工作得很好,当我滚动表视图时,我可以在调试控制台中看到SELECT语句。但它在发布时仍然会排序4302行,我觉得这不必要地减慢了应用程序的发布时间

根据苹果公司的WWDC 2010示例代码,我打算在NSSortDescriptor中实现一个规范化的字符串排序和一个不区分大小写的EnumericCompare选择器,但在我看来,这里缺少了一些简单的东西

更新: 似乎我不能使用自定义选择器caseInsensitiveNumericCompare:with NSSortDescriptor,因为我使用SQLite作为数据库。我真的不知道我还能做些什么来加速这一切。也许SQLite会使用缩短和规范化的字符串更快地排序,这就是我下一步要尝试的

更新2:
使用标准化字符串(除A-Z和0-9外,没有其他字母或符号),启动时间将降低到0.7秒左右。降价幅度不大。我尝试的最后一件事是对数据库进行预排序,然后为行分配增量ID。在NSSortDescriptor中,我将按照这个数字id进行排序。根据我的SQL测试,它应该快7倍左右。

我解决了自己的问题。这只是提醒任何可能遇到类似问题的人我犯的错误是没有为数据库端的必填字段创建索引。我只是在XCode中单击了模型中的“索引”选项。显然,如果您自己提供了.sqlite文件,那么这不会创建任何索引

在一个奇怪的启动案例之后,Core Data决定为我创建数据库,我看到执行了以下SQL语句:

2011-10-08 19:49:40.572 App[1717:307] CoreData: sql: CREATE INDEX ZINFO_ZREGISTERED_NAME_INDEX ON ZINFO (ZREGISTERED_NAME)
2011-10-08 19:49:40.586 App[1717:307] CoreData: sql: CREATE INDEX ZINFO_ZFIRSTLETTER_INDEX ON ZINFO (ZFIRSTLETTER)
2011-10-08 19:49:40.598 App[1717:307] CoreData: sql: CREATE INDEX ZINFO_ZNAME_INDEX ON ZINFO (ZNAME)
2011-10-08 19:49:40.610 App[1717:307] CoreData: sql: CREATE INDEX ZINFO_ZN_SL_NAME_INDEX ON ZINFO (ZN_SL_NAME)
2011-10-08 19:49:40.622 App[1717:307] CoreData: sql: CREATE INDEX ZINFO_ZN_REGISTERED_NAME_INDEX ON ZINFO (ZN_REGISTERED_NAME)
2011-10-08 19:49:40.635 App[1717:307] CoreData: sql: CREATE INDEX ZINFO_ZDETAILS_INDEX ON ZINFO (ZDETAILS)
在我将这些索引复制到自己的数据库中之后,速度大大加快:

CoreData: sql: SELECT 0, t0.Z_PK FROM ZINFO t0 ORDER BY t0.ZREGISTERED_NAME
CoreData: annotation: sql connection fetch time: 0.1315s
CoreData: annotation: total fetch execution time: 0.1568s for 4161 rows.
我对这些数字非常满意。但由于我现在已经对数据库进行了预排序,我可以为NSSortDescriptor使用一个数字。这使我想到:

CoreData: sql: SELECT 0, t0.Z_PK FROM ZINFO t0 ORDER BY t0.ZID
CoreData: annotation: sql connection fetch time: 0.0677s
CoreData: annotation: total fetch execution time: 0.0890s for 4161 rows.

所以从十分之九秒降到百分之九秒以下。

你能分享一下你的项目吗?我有点想看看它
CoreData: sql: SELECT 0, t0.Z_PK FROM ZINFO t0 ORDER BY t0.ZID
CoreData: annotation: sql connection fetch time: 0.0677s
CoreData: annotation: total fetch execution time: 0.0890s for 4161 rows.