2016-07-13 7 views
0

Meine Datenbank hat 500.000 Datensätze. Die Tabellen haben keinen Primärschlüssel, da Realm keine zusammengesetzten Primärschlüssel unterstützt. Ich hole Daten im Hintergrund Thread, dann möchte ich es in der Benutzeroberfläche auf dem Haupt-Thread anzeigen. Aber da Realm-Objekte nicht über Threads gemeinsam genutzt werden können, kann ich den im Hintergrund abgerufenen Datensatz nicht verwenden. Stattdessen muss ich den Datensatz im Hauptthread abrufen? Wenn ich einen Datensatz aus den 500.000 Datensätzen abrufe, wird der Haupt-Thread blockiert. Ich weiß nicht, wie ich damit umgehen soll. Ich benutze Realm, weil es sagt, dass es schnell genug ist. Wenn ich den Datensatz mehrmals abrufen muss, ist er dann wirklich schneller als SQLite? Ich möchte keine andere Eigenschaft erstellen, die andere Spalten als Primärschlüssel kombiniert, weil die Realm-Datenbank bereits größer als eine SQLite-Datei ist.Wie verbessert man die Leistung für große Datensätze mit Realm?

@objc class CKPhraseModel: CKBaseHMMModel{ 
    dynamic var pinyin :String! 
    dynamic var phrase :String = "" 

    class func fetchObjects(apinyin :String) -> Results<CKPhraseModel> { 

     let realm = Realm.createDefaultRealm() 

     let fetchString = generateQueryString(apinyin) 
     let phrases = realm.objects(self).filter(fetchString).sorted("frequency", ascending: false) 

     return phrases 
    } 

    func save(needTransition :Bool = true) { 

     if let realm = realm { 
      try! realm.write(needTransition) {[unowned self] in 
       self.frequency += 1 
      } 
     } 
     else { 
      let realm = Realm.createDefaultRealm() 
      if let model = self.dynamicType.fetchObjects(pinyin).filter("phrase == %@", phrase).first { 
       try! realm.write(needTransition) {[unowned self] in 
        model.frequency += self.frequency 
       } 
      } 
      else { 
       try! realm.write(needTransition) {[unowned self] in 
        realm.add(self) 
       } 
      } 
     } 
    } 
} 

dann speichere ich geholt Aufzeichnungen in Array

let userInput = "input somthing" 
let phraseList = CKPhraseModel().fetchObjects(userInput) 
for (_,phraseModel) in phraseList.enumerate() { 
    candidates.append(phraseModel) 
} 

Dann möchte ich candidates Informationen in UI angezeigt werden, wenn der Benutzer eine dieser klickt. Ich werde CKPhraseModels save Funktion aufrufen, um Änderungen zu speichern. Dieser Schritt ist im Hauptthread.

+0

Realm funktioniert tadellos mit MainThread & Background Thread. Das Problem besteht darin, dass Sie Realm, RealmObject oder RealmResults nicht über Threads hinweg weitergeben können. Also, in Ihrem Anwendungsfall, holen Sie sich die Datensätze aus dem Hintergrund Thread speichern Sie die Daten im Hintergrund Thread in Realm, und holen Sie sich die Datensätze aus Realm in MainThread mit ASYNC Methoden von Realm. –

+0

Folgen Sie diesem Beispiel, wenn Sie nach tatsächlichem Code suchen https://github.com/viraj49/Realm_android-injection-rx-test –

+0

@VirajTank Ich hole die Datensätze aus dem Hintergrundthread. Dann speichere ich abgerufene Datensätze in einem Array. Ich zeige es auf der Benutzeroberfläche an. Wenn der Benutzer auf einen davon klickt. Ich speichere es im Hintergrund Thread in Realm. Die Thread-Zeile ist wie folgt: 'background thread => main thread => background thread', Wenn ich denselben Datensatz mehrmals abrufe. ob es die App-Leistung reduziert? Meine App führt den Prozess mit Benutzereingabe ein Wort aus. So ist es sehr häufig, Daten zu holen und Daten mit großer Datenbank zu speichern. – kai

Antwort

1

Realm ist schnell, wenn Sie seine Lazy Loading-Fähigkeit verwenden, was bedeutet, dass Sie einen Filter erstellen, der Ihre candidates direkt aus dem Realm zurückgibt, weil Sie dann nur die Elemente abrufen müssen, die Sie in den Ergebnissen indexieren.

In Ihrem Fall kopieren Sie ALLE Elemente aus. Das ist ein bisschen langsam, weshalb du am Ende frierst.

+0

Wenn ich nicht ausführen 'lassen userinput = "input Somthing" lassen phraseList = CKPhraseModel(). FetchObjects (userinput) für (_, phraseModel) in phraseList.enumerate() { candidates.append (phraseModel) } 'um das Ergebnis zu kopieren. Wie kann ich den Kandidaten in der Benutzeroberfläche im Hauptthread anzeigen? Die Ergebnisse werden im Hintergrundthread abgerufen. Ich kann es nicht verstehen. Wie soll ich es machen ? – kai

+0

... aber wenn die Ergebnisse kopiert und aus dem Hintergrund in die Benutzeroberfläche abgerufen werden, sollte dies nicht einmal einfrieren. Der Fehler ist woanders. – EpicPandaForce

+0

Wenn ich die for-Schleife ausführe, ändere ich sie, um ein neues 'CKPhraseModel' zu erstellen, das nicht von Realm verwaltet wird, um alle Eigenschaften von' phraseModel' in 'phraseList' zu kopieren. So kann ich es im UI-Thread verwenden. Da das Objekt nicht von Realm verwaltet wird, kann ich es über Thread hinweg verwenden. Ich habe kein gutes Ideal, um damit umzugehen. Ich weiß nicht, ob ich ein Missverständnis bin! – kai