问题
I have 2 entities: Components & SurveyReadingWeb that have a one-to-many relationship. I have saved Components data in core data database; but while saving SurveyReadingWeb -- in a for loop -- I have to fetch Components data entity by passing component id and setting the surveyreadings isComponentexists relationship, like in the code below for 8000 records. This process is taking too much time, nearly 7 minutes. How can I reduce the time?
for item in items {
autoIncrementId = autoIncrementId + 1
print("reading items parsed:- \(item.SurveyReadingId), \(autoIncrementId)")
let reading : SurveyReadingWeb? = NSEntityDescription.insertNewObject(forEntityName: Constants.EntityNames.kSURVEYREADINGWEB, into: self.managedContext) as? SurveyReadingWeb
reading?.surveyId1 = Int32(autoIncrementId)
reading?.surveyId = Int32(item.SurveyId) ?? 0
reading?.readingData = item.CH4
reading?.surveyDateTime = item.SurveyReadingDateTime
reading?.latitude = item.Latitude
reading?.longitude = item.Longitude
reading?.serialNumber = item.SerialNumber
reading?.descriptionText = item.Description
reading?.componentName = item.Description
reading?.componentId = Int32(item.ComponentId) ?? 0
reading?.readingTypeId = Int32(item.ReadingTypeID) ?? 0
reading?.readingTypeDetails = item.ReadingTypeDetails
reading?.currentLatitude = item.CurrentLatitude
reading?.currentLongitude = item.CurrentLongitude
reading?.hdop = item.HDOP
reading?.vdop = item.VDOP
reading?.componentDistance = item.ComponentDistance
reading?.facilityId = Int32(item.ProjectId) ?? 0
reading?.posted = 1
reading?.readyToSync = 1
reading?.isComponentExists = DatabaseManager.sharedManager.getCompNameFromID(compID: Int32(item.ComponentId) ?? 0)
}
saveContext()
func getCompNameFromID(compID : Int32) -> Components? {
var component : Components? = nil
let fetchRequest : NSFetchRequest<Components> = Components.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "componentId == %ld", compID)
do {
let searchResults = try managedContext.fetch(fetchRequest)
component = (searchResults.first) ?? nil
} catch {
}
return component ?? nil
}
回答1:
You can reduce the time dramatically if you add an NSCache
instance to cache compID:Components
key value pairs.
In getCompNameFromID
check if the compID
exists in the cache. If yes get the value from the cache (very fast), if not fetch the record and save it for the compID
in the cache.
And use the convenient SurveyReadingWeb(context:
initializer to get rid of all the ugly question marks, however the performance benefit is rather tiny.
来源:https://stackoverflow.com/questions/62087792/core-data-taking-time-to-insert-records-with-fetching-entity-set-as-relationsh