Frage

Ich habe 2 Einheiten, A und B, die eine viel zu viele Beziehung haben.

Die A Unternehmen hat über 10.000 Objekte in und B hat etwa 20 Objekte.

Grundsätzlich können Objekte zu einem oder mehrere B-Objekten in Beziehung gesetzt werden, und die B-Objekte zu verfolgen, welche A-Objekte mit denen sie verbunden sind. Dies wird mit der inversen Beziehung Einstellung gemacht.

Ich möchte nur all B-Objekt zurückzugeben, die nicht zu einem A-Objekt verknüpft ist. Die Abruf- ich verwende, ist dies:

NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
[fetch setIncludesPropertyValues:NO];
[fetch setEntity:[NSEntityDescription entityForName:@"B" inManagedObjectContext:context]];
[fetch setPredicate:[NSPredicate predicateWithFormat:@"aObjects.@count == 0"]];
return [context executeFetchRequest:fetch error:nil];

Es ist jedoch das Abruf Ausführung eine sehr lange Zeit in Anspruch nimmt, ca. 30 Sekunden. Ich verstehe das nicht, denn obwohl es eine große Anzahl von A-Objekten ist, diese holen nichts mit ihnen zu tun hat, und muss nur die 20 B-Objekte überprüfen.

Wenn ich das Prädikat Kommentar aus, so dass die Rendite Objekte alle B holen, dann holen die wirklich schnell ist, wie sie nur das Abrufen 20 Objekte erwarten würde. So scheint es, dass das Prädikat einig A beteiligt ist immer Objekte und verursacht es eine lange Zeit in Anspruch nehmen!

Schuppen Kann jemand irgendein Licht auf, warum das so lange dauert?

Edit:

Ich habe SQL Debug-Informationen bekommen und hier ist, was Ausgang ist:

CoreData: sql: SELECT t0.Z_ENT, t0.Z_PK FROM ZTABLEVIEWOBJECT t0 WHERE ((SELECT COUNT(*) FROM ZTABLEVIEWOBJECT t1 JOIN Z_10BOBJECTS t2 ON t1.Z_PK = t2.Z_10AOBJECTS3 JOIN ZTABLEVIEWOBJECT t3 ON t2.Z_12BOBJECTS = t3.Z_PK WHERE (t0.Z_PK = t2.Z_12BOBJECTS) ) = ? AND  t0.Z_ENT = ?) 
CoreData: annotation: sql connection fetch time: 49.4198s
CoreData: annotation: total fetch execution time: 49.4240s for 0 rows.

I sollte hinzufügen, dass beide Einheit A und Einheit B, vererben (einen Elternteil haben) eine gemeinsame TableViewObject Einheit, die gemeinsamen Werte zwischen dem beide (Sektionsnamen und Sortiernamen usw. wie Tabellenansicht) hält. Hoffe, das hilft!

War es hilfreich?

Lösung

Wenn ich Sie richtig bin zu verstehen, haben Sie eine viele-zu-viele-Beziehung zwischen diesen Objekten und die das Problem verursachen können. In einer many-to-many gibt es eine Join-Tabelle zwischen B und A und der Join-Tabelle wahrscheinlich hart getroffen wird immer. Ich würde sehr gespannt sein, die SQL, um zu sehen, die mit Ihrem holen erzeugt wird.

UPDATE

Versuchen Sie Ihr Prädikat ändern „aObjects == null“ zu sein und sehen, was passiert. Da es sich um eine many-to-many-Beziehung, die die einzige andere Prädikat ist, dass ich daran denken kann, Macht geben Sie die Ergebnisse, die Sie suchen.

Andere Tipps

Sie ersetzen

aObjects.@count == 0

mit

ANY aObjects == nil

Es wird drastisch die Zeit meines query (iPhone OS 3.0) reduzieren. Es funktioniert auch für != nil (@count != 0).

Wenn Sie einen SQLite-Speicher verwenden, können Sie auf SQL-Fehlerprotokollierung aktivieren. Core Data protokolliert alle SQL-Befehle es an die Konsole zu machen. Ich habe dies sehr nützlich fand etwas Unerwartetes passiert hinter den Kulissen zu entdecken. Es wird auch Zeitinformationen für jeden SQL-Befehl auszudrucken!

Um dies zu tun, doppelklicken Sie auf die ausführbare Datei in Ihrem Projekt, gehen Sie auf die Argumente Registerkarte und fügen Sie ein Argument:

-com.apple.CoreData.SQLDebug 1

Ich denke, das ist ein wenig spät, aber vielleicht dies helfen wird, andere, die in dieses Problem. Die umgekehrte Beziehung auf bObjects ist ein Attribut von bObjects und als NSSet in bObjects dargestellt. Wenn entweder der NSSet nil oder die Anzahl der Objekte in der NSSet ist gleich Null ist, dann gibt es keine aObjects auf die jeweilige bObject bezogen.

Test für die aObjects.@count erfordert beide Tabellen repräsentieren die Objekte abgefragt werden und einige wirklich hässliche SQL erzeugt. Was Sie versuchen, hier muss nicht weiter dann die bObject.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top