我正在开发一个定期从服务器下载数据的应用程序。如果数据需要更新,我会使用类似以下内容来更新记录或插入新记录(如果不存在)。
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Trip")
for csvTrip in csvTrips {
var trip: NSManagedObject!
let tripId = Int(csvTrip[0])!
fetchRequest.predicate = NSPredicate(format: "id = %d", tripId)
if (context.count(for: fetch) == 0) {
trip = NSEntityDescription.insertNewObject(forEntityName: "Trip", into: context)
trip.setValue(tripId, forKey: "id")
} else {
tripObject = (context.fetch(fetch) as! [NSManagedObject])[0]
}
// Set other properties
}
检查每个循环中的实体是否已经存在,比不检查而直接插入实体要慢约 100 倍,这对于超过几千个实体来说是一个大问题。我已经尝试先获取所有实体,但我仍然必须循环遍历每个实体并将 id 添加到数组或其他内容中,这并没有快多少。我知道核心数据与 MySQL 不一样,但我很难相信没有类似 INSERT ... ON DUPLICATE KEY UPDATE 的功能,这在 MYSQL 中速度非常快。我错过了什么吗?
如果获取甚至几千个实体并将 id 加载到Set
花了特别长的时间。
你可以使用类似的东西:
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Trip")
fetchRequest.resultType = .dictionaryResultType
fetchRequest.propertiesToFetch = ["id"]
do {
if let results = try self.moc.fetch(fetchRequest) as? [[String:Any]] {
let idSet = Set<Int32>(results.flatMap({ (dict) -> Int32? in
return dict["id"] as? Int32
}))
}
} catch {
print("Error reading trips")
}
现在您可以轻松检查给定的 id 是否是新的,并根据需要插入新的行程:
for csvTrip in csvTrips {
if let tripId = Int(csvTrip[0]) {
if !idSet.contains(tripId) {
trip = NSEntityDescription.insertNewObject(forEntityName: "Trip", into: context)
trip.setValue(tripId, forKey: "id")
}
}
}
在我的测试中,将 320,000 个行程 ID 加载到集合中需要 1.35 秒,创建 10,000 个新行程需要 0.08 秒,同时检查行程 ID 是否包含在集合中。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)