2016-09-27 65 views
0

我有25000個記錄,每次應用程序啓動時都從Web服務中檢索到這些記錄。 在初始化階段,我想將所有這些項目保存到核心數據中。 此操作的時間約爲20分鐘。 可以更快地將所有項目保存到核心數據中嗎? 這是一個好主意,使用sqlite工具將它們保存到sqlite數據庫,然後實例化核心數據?核心數據大量

編輯:

保存到核心數據20分鐘。

func storeDevices(_ dataStack: DATAStack,value: [JSON]) -> Bool 
{ 
    dataStack.performInNewBackgroundContext { backgroundContext in 
    let entityDevices = NSEntityDescription.entity(forEntityName: "Devices", in: backgroundContext) 

    for item in value 
    { 
     if !item["event_id"].stringValue.isEmpty 
     { 
      let id = item["id"].stringValue 
      let predicate = NSPredicate(format: "%K == %@", "id", id) 
      let typesFetchRequest = NSFetchRequest<Devices>(entityName: "Devices") 
      typesFetchRequest.predicate = predicate 
      do { 
       let fetchedTypesResults = try backgroundContext.fetch(typesFetchRequest) as! [Devices] 
       if (fetchedTypesResults.count > 0) 
       { 
        let typeUpdate = fetchedTypesResults[0] 
        switch item["is_Deleted"].stringValue 
        { 
        case "true": 
         typeUpdate.setValue(true, forKey: "deletedStatus") 
        case "false": 
         typeUpdate.setValue(false, forKey: "deletedStatus") 
        default: 
         typeUpdate.setValue(false, forKey: "deletedStatus") 
        } 

        if let intVersion = Int(item["last_modified"].stringValue) { 
         typeUpdate.setValue(intVersion, forKey: "lastModified") 
        } else { 
         typeUpdate.setValue(NSNumber(value: 0 as Int32), forKey: "lastModified") 
        } 

        typeUpdate.setValue(NSNumber(value: 0 as Int32), forKey: "syncStatus") 

        typeUpdate.setValue(item["deviceUUID"].stringValue, forKey: "deviceUUID") 
        typeUpdate.setValue(item["deviceLocation"].stringValue, forKey: "deviceLocation") 

        let event_id = item["event_id"].stringValue 
        if !event_id.isEmpty 
        { 

         let predicate = NSPredicate(format: "%K == %@", "id", event_id) 
         let typesFetchRequest = NSFetchRequest<Events>(entityName: "Events") 
         typesFetchRequest.predicate = predicate 

         do { 
          let fetchedTypesResults = try backgroundContext.fetch(typesFetchRequest) as! [Events] 
          if (fetchedTypesResults.count > 0) 
          { 
           typeUpdate.setValue(fetchedTypesResults[0], forKey: "event") 
          } 
          else 
          { 
           continue 
          } 
         } catch { 
          let saveError = error as NSError 
          print("Failed to fetch events in Devices: \(saveError)") 
         } 
        } 


        continue 
       } 

      } catch { 
       fatalError("Failed to fetch devices: \(error)") 
      } 

      let deviceNewElement = Devices(entity: entityDevices!, insertInto: backgroundContext) 
      deviceNewElement.id = id 
      switch item["is_Deleted"].stringValue 
      { 
      case "true": 
       deviceNewElement.deletedStatus = true 
      case "false": 
       deviceNewElement.deletedStatus = false 
      default: 
       deviceNewElement.deletedStatus = false 
      } 

      if let intVersion = Int(item["last_modified"].stringValue) { 
       deviceNewElement.lastModified = intVersion as NSNumber? 
      } else { 
       deviceNewElement.lastModified = NSNumber(value: 0 as Int32) 
      } 

      deviceNewElement.deviceUUID = item["deviceUUID"].stringValue 
      deviceNewElement.deviceLocation = item["deviceLocation"].stringValue 

      let event_id = item["event_id"].stringValue 
      if !event_id.isEmpty 
      { 
       let predicate = NSPredicate(format: "%K == %@", "id", event_id) 
       let typesFetchRequest = NSFetchRequest<Events>(entityName: "Events") 
       typesFetchRequest.predicate = predicate 

       do { 
        let fetchedTypesResults = try backgroundContext.fetch(typesFetchRequest) as! [Events] 
        if (fetchedTypesResults.count > 0) 
        { 
         deviceNewElement.event = fetchedTypesResults[0] 
        } 
        else 
        { 
         continue 
        } 
       } catch { 
        let saveError = error as NSError 
        print("Failed to fetch events in Devices: \(saveError)") 
       } 
      } 

      deviceNewElement.syncStatus = NSNumber(value: 0 as Int32) 
     } 
    } 
     try! backgroundContext.save() 
    } 
    return true 

} 
+0

兩點操作需要20分鐘,是20分鐘才能檢索並存儲數據,如果是這樣的話,20分鐘的什麼部分被佔用,只是檢索數據。第二點是我相信core-data使用sqlite來存儲數據,所以我沒有看到最初如何使用sqlite數據庫,然後轉換爲核心數據將會爲您節省時間。然而,作爲一個SQLite數據庫存儲,然後使用它,而不是核心數據可能會給你一個優勢 –

+2

你是什麼意思在這裏「保存到SQLite數據庫?」什麼sqlite數據庫?核心數據在很多情況下都是在sqlite的基礎上實現的,但不應該直接修改數據庫。這不是一個公共模式。核心數據是一個持久對象圖。它不是一個數據庫(它沒有「行」和「列」,即使它可以存儲在某些東西中)。如果你想使用一個數據庫(如sqlite),那很好,但不要嘗試像使用核心數據一樣使用原始SQL。核心數據工具提供的信息是關於您的時間花在哪裏的? –

+1

是的,應該可以更快地做到這一點。但是你需要描述(或更好地展示)你的代碼在做什麼。沒有看到它就不可能幫助優化代碼。 –

回答

0

你需要優化你如何使用CoreData。

處理您的數據並確定需要觸摸哪些ManagedObjects,並在環路外批量預取這些數據。注意可能還需要預取的任何關係。你不想讓錯誤持續發射。

現在通過並進行所有更改。最後保存一次。

如果內存壓力很大,將數據分成幾千塊並按上述方式處理它們。使用@autoreleasepool。

0

是的,最好使用sqlite3函數做批量插入。由於在覈心數據中不可能這樣做。

0

它不應該花20分鐘來保存25000條記錄,你是否嘗試過啓動多個線程和上下文並將它們保存到coredata中。請分享您的示例代碼,我們可以提供幫助。下面是一個示例代碼薈萃採取更少的時間保存到磁盤

loop and create threads for every 1000 records using dispatch_async etc 
on each thread, call dispatch_enter, create a thread context taken from parent root context 
loop the 1000 records of this thread and upsert (update or insert) them into the context 
save the context and call dispatch_leave 
Finally know that everything is saved in dispatch_notify