Sqlite或Core Data来更新50000条记录
我目前正在为我的项目使用coredata。 但是,当API返回应用程序需要更新的54000个对象时,用户必须等待近2个小时。 这是当前项目的主要问题,我正在考虑使用sqlite而不再使用coredata来更新数千个对象。
使用Sqlite是否是正确的决定还是CoreData有任何建议? 我无法决定。 任何帮助都会很棒。 谢谢。
这是我正在做的事情:
NSManagedObjectContext *privateObjectContext = [AppDelegate appDelegate].privateManagedObjectContext;
[privateObjectContext performBlock:^{
int i = 1;
for (NSDictionary *item in itemlist) {
i++;
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:
@"itemID == %@",[item objectForKey:@"item_id"]
]];
NSError *error;
NSMutableArray *inventories = [[NSMutableArray alloc]initWithArray:
[privateObjectContext executeFetchRequest:fetchRequest
error:&error]];
ItemManagedObject *itemMO;
if(inventories.count){
itemMO = inventories.firstObject;
}else{
itemMO = [NSEntityDescription insertNewObjectForEntityForName:@"ItemObject"
inManagedObjectContext:privateObjectContext];
}
[itemMO prepareWithDictionary:item];
}
NSError *error;
if (![privateObjectContext save:&error]) {
completionHandler(NO);
}
}
2小时很长。 这很奇怪。
然而,你可以通过让核心数据做更少的工作来按摩你的代码。 更少的工作。
这将显着减少Core Data所执行的工作量以及应用程序的性能。
第二点很简单,但非常详细:在调用setter之前,比较每个单独的属性值与字典值。
第一点需要改变算法:
执行单个提取请求,按id排序(使用[NSFetchRequest setSortDescriptors:])
按id排序字典(使用[NSArray sortedArray ...])
同步两个排序列表(两个列表排序都是最重要的):
NSEnumerator *itemMOEnum = [itemMOs objectEnumerator];
NSEnumerator *dicEnum = [dictionaries objectEnumerator];
ItemManagedObject *itemMO = [itemMOEnum nextObject];
NSDictionary *itemDic = [dicEnum nextObject];
while (itemDic) {
NSComparisonResult comparison = itemMO ? [itemDic[@"item_id"] compare:itemMO.itemID] : NSOrderedAscending;
switch (comparison) {
case NSOrderedSame:
// id present in both lists: update
[itemMO prepareWithDictionary:itemDic];
itemMO = [itemMOEnum nextObject];
itemDic = [dicEnum nextObject];
break;
case NSOrderedAscending: {
// id present only in dictionaries: create
itemMO = [NSEntityDescription insertNewObjectForEntityForName:@"ItemObject"
inManagedObjectContext:privateObjectContext];
[itemMO prepareWithDictionary:itemDic];
itemDic = [dicEnum nextObject];
} break;
case NSOrderedDescending:
// id present only in managed object: delete or do nothing
itemMO = [itemMOEnum nextObject];
break;
}
}
while (itemMO) {
// id present only in managed object: delete or do nothing
itemMO = [itemMOEnum nextObject];
}
并保存。
最后,也许SQLite会更快(请参阅https://github.com/groue/GRDB.swift/wiki/Performance,以便比较Core Data与SQLite库的性能)。
但SQLite不会将慢速算法变成快速算法 。
核心数据提供NSBatchUpdateRequest
,它允许您直接在持久性存储上进行更新,而不涉及在内存中实例化和处理管理对象。
您应该使用核心数据性能工具来运行此代码。 如果itemList
包含54,000个对象,那么您将对持久性存储执行54,000次提取,以每次检查一个ID。 要提前获取所有ID,然后检查内存中的结果比执行重复提取请求要快得多 - 原始SQL中的代码几乎与核心数据中的代码一样慢。
此代码也看起来不正确:
ItemManagedObject *itemMO;
if(itemMO.count){
如果测试不会通过,除非你在某个地方错过了一条线。
我从来没有在sqlite中重做过核心数据项目,反之亦然。 所以我不能告诉你是否存在性能差异/
然而54k = 2小时的事情听起来很奇怪。 你谈论的是一个API,它让我怀疑涉及服务器,你的问题是关于数据库。 当然,2小时听起来太长了,让我怀疑你的数据库的核心设计是否有问题。 例如,缺乏索引。 根据您的查询和数据库,单个更新可能会触发各种重型处理。
另一种是你为什么要在设备上处理这一列数据。 需要处理很多事情,我想知道是否有办法减少音量,选择性地进行更新,或者甚至更好 - 将其移动到服务器。
我认为你需要重新考虑你的问题。 提供关于数据库的更多上下文,正是你在做什么以及为什么。
链接地址: http://www.djcxy.com/p/78201.html上一篇: Sqlite or Core Data to update more then 50000 records
下一篇: SQLite snippet function implementation does not format Text as HTML in TextView