Objective c SQL与核心数据的真实性能:需要透视图和可能的特定修复
我有一个文字游戏应用程序,可以访问文字和线索列表,大约有10万条条目。数据库仅可访问,从未更改。我使用SQL方法构建了这个应用程序,它在iOS 6上运行得非常好,但在iOS 5上从数据库中获取新线索的时间非常慢:Objective c SQL与核心数据的真实性能:需要透视图和可能的特定修复,objective-c,sql,ios,core-data,Objective C,Sql,Ios,Core Data,我有一个文字游戏应用程序,可以访问文字和线索列表,大约有10万条条目。数据库仅可访问,从未更改。我使用SQL方法构建了这个应用程序,它在iOS 6上运行得非常好,但在iOS 5上从数据库中获取新线索的时间非常慢: iOS5使用SQL从100K中获取一条记录,大约需要12分钟 秒 iOS 6使用SQL从100K中获取一条记录需要 大约700-1000毫秒 这两款手机都安装在32 GB的iPod Touch上 考虑到这种性能,我使用核心数据制作了一个版本。我的方法是通过首先计算符合查询的记录,然
- iOS5使用SQL从100K中获取一条记录,大约需要12分钟 秒
- iOS 6使用SQL从100K中获取一条记录需要 大约700-1000毫秒
- iOS 5,计数记录大约需要4秒,检索其中一个 这些记录大约需要50-1500毫秒。总时间约为5秒
- iOS 6,计数记录需要2秒多一点的时间,检索 其中一条记录大约需要300-500毫秒。总共大约3秒钟
- (NSArray *) randomClue {
NSManagedObjectContext* context = [self managedObjectContext];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"A"];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"WL28"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [self createSearchQuery];
[fetchRequest setPredicate:predicate];
NSError *error;
NSDate *date1 = [NSDate date];
NSString *timeString1 = [formatter stringFromDate:date1];
int resCount = [context countForFetchRequest:fetchRequest
error:&error];
NSDate *date2 = [NSDate date];
NSString *timeString2 = [formatter stringFromDate:date2];
int t1 = [timeString1 intValue];
int t2 = [timeString2 intValue];
int d1 = t2-t1;
NSLog(@"randomClue:");
NSLog(@" Time to count array entries: %i", d1);
int ranNum = arc4random_uniform(resCount-1);
int ranNum2 = ranNum + 1;
// Now we fetch just one answer object, not a whole database or even a piece of it!
[fetchRequest setReturnsObjectsAsFaults:YES];
[fetchRequest setPropertiesToFetch:nil];
[fetchRequest setFetchLimit:1];
[fetchRequest setFetchOffset:ranNum2];
NSDate *date3 = [NSDate date];
NSString *timeString3 = [formatter stringFromDate:date3];
self.wl28 = [context executeFetchRequest:fetchRequest error:&error];
NSDate *date4 = [NSDate date];
NSString *timeString4 = [formatter stringFromDate:date4];
int t3 = [timeString3 intValue];
int t4 = [timeString4 intValue];
int d2 = t4-t3;
NSLog(@" Time to retrieve one entry: %i", d2);
return self.wl28;
}
编辑:下面添加createSearchQuery
- (NSPredicate *)createSearchQuery {
NSMutableArray *pD = [[GameData gameData].curData valueForKey:@"persData"];
NSNumber *currMin = [pD objectAtIndex:0];
NSNumber *currMax = [pD objectAtIndex:1];
NSNumber *dicNo = [pD objectAtIndex:2];
NSString *dict = nil;
if ([dicNo intValue] == 0) dict = @"TWL";
if ([dicNo intValue] == 1) dict = @"LWL";
NSPredicate *dictPred = [NSPredicate predicateWithFormat:@"dict == %@", dict];
NSPredicate *lowNoCPred = [NSPredicate predicateWithFormat:@"noC >= %@", currMin];
NSPredicate *highNoCPred = [NSPredicate predicateWithFormat:@"noC <= %@", currMax];
NSPredicate *query = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray
arrayWithObjects:dictPred, lowNoCPred, highNoCPred,nil]];
NSLog(@"%@", query);
return query;
}
-(NSPredicate*)createSearchQuery{
NSMUTABLEARRY*pD=[[GameData GameData].curData valueForKey:@“persData”];
NSNumber*currMin=[pD objectAtIndex:0];
NSNumber*currMax=[pD objectAtIndex:1];
NSNumber*dicNo=[pD objectAtIndex:2];
NSString*dict=nil;
如果([dicNo intValue]==0)dict=@“TWL”;
如果([dicNo intValue]==1)dict=@“LWL”;
NSPredicate*dictPred=[NSPredicate PREDITEWITHFORMAT:@“dict==%@”,dict];
NSPredicate*lowNoCPred=[NSPredicate谓词格式:@“noC>=%@”,currMin];
NSPredicate*highNoCPred=[NSPredicate谓词格式:@"noC您可以尝试向实体中的noC和/或dict属性添加索引。这可能会加快查询时间。如果数据库是只读的,为什么每次都要计算条目?根据用户设置,会有子集,这反过来会影响查询。最大的子集约为70K,这就是性能数字rs是基于的。它们的数量不是无限的,所以我想我可能会预先计算它们以节省一些时间。如果您向我们展示createSearchQuery
方法,这会更容易。@TomaszZabłocki感谢您的关注:我将代码添加到了原始帖子中。您能给我指一些文档吗?我已经看到提到了索引C在Xcode中打开xcdatamodel,切换到网格编辑器样式,然后选择您的实体,然后选择属性noC或dict。在右侧选择它之后,您就有了数据模型检查器。在Xcode中打开xcdatamodel,然后选择属性noC或dictmply检查一下。很棒的呼叫!这将在iOS 6上检索单个条目的时间减少到大约50-200毫秒。计数条目的时间几乎没有变化。有没有关于加快速度的建议?我想我可以在dict
和noC
的每个可能组合上硬连线条目的数量,如果需要的话,这将回复快速查找即可完成该步骤。另一个提示:您可以使用NSFetchedResultsController只查询一次,并将其保留到应用程序终止。这样您就可以从fetchedObjects属性中选择随机对象,从而将两次调用的时间减少到~0。再次感谢。我将研究NSFetchedResultsController,或者我可以做些什么imilar:当用户更改设置时,从主数据库中提取的线索子集很少发生更改。因此,我可以将其在数组中保留一段时间,并从中随机获取。感谢您的帮助!接受答案。