2

多対多の関係を持つ A と B の 2 つのエンティティがあります。

A エンティティには約 10,000 個のオブジェクトがあり、B エンティティには約 20 個のオブジェクトがあります。

基本的に、A オブジェクトは 1 つ以上の B オブジェクトに関連付けることができ、B オブジェクトはどの A オブジェクトに接続されているかを追跡します。これは、逆関係の設定で行われます。

A オブジェクトに関連しないすべての B オブジェクトを返したいだけです。私が使用しているフェッチはこれです:

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];

ただし、フェッチの実行には非常に長い時間がかかります。30秒。A オブジェクトが多数あるにもかかわらず、このフェッチはそれらとは関係なく、20 個の B オブジェクトをチェックする必要があるだけなので、これはわかりません。

フェッチがすべての B オブジェクトを返すように述語をコメントアウトすると、20 個のオブジェクトをフェッチするだけで期待どおり、フェッチは非常に高速になります。したがって、その述語がいくつかの A オブジェクトを巻き込んでいて、長い時間がかかっているように見えます。

なぜこれに時間がかかるのか、誰かが光を当てることができますか?

編集:

SQL デバッグ情報を取得しました。出力は次のとおりです。

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.

エンティティ A とエンティティ B の両方が共通の TableViewObject エンティティを継承する (親を持つ) ことを追加する必要があります。これは、2 つの間で共通の値 (テーブル ビュー セクション名や並べ替え名など) を保持します。お役に立てれば!

4

4 に答える 4

4

あなたは交換することができます

aObjects.@count == 0

ANY aObjects == nil

クエリの時間を大幅に短縮します (iPhone OS 3.0)。!= nil( )にも有効です@count != 0

于 2010-03-22T16:42:31.990 に答える
3

SQLite ストアを使用している場合は、SQL デバッグ ログを有効にすることができます。Core Data は、作成しているすべての SQL コマンドをコンソールに記録します。これは、舞台裏で予期せぬことが起こっていることを発見するのに非常に役立つことがわかりました。また、各 SQL コマンドのタイミング情報も出力されます!

これを行うには、プロジェクトで実行可能ファイルをダブルクリックし、[引数] タブに移動して、引数を追加します。

-com.apple.CoreData.SQLDebug 1
于 2010-01-04T15:42:44.287 に答える
1

私が正しく理解していれば、これらのオブジェクト間に多対多の関係があり、それが問題を引き起こしている可能性があります。多対多では、B と A の間に結合テーブルがあり、その結合テーブルはおそらく大きな打撃を受けています。あなたのフェッチで生成されている SQL を見てみたいと思います。

アップデート

述語を「aObjects == nil」に変更してみて、何が起こるかを確認してください。これは多対多の関係であるため、私が考えることができる唯一の他の述語であり、探している結果が得られる可能性があります。

于 2010-01-04T16:41:11.003 に答える
0

これは少し遅いと思いますが、おそらくこれはこの問題に遭遇した他の人を助けるでしょう。の逆の関係bObjectsはの属性でbObjectsあり、で表されNSSetますbObjectsNSSetisnilまたはis内のオブジェクトの数のいずれかNSSetがゼロの場合aObjects、特定のに関連するものはありませんbObject

のテストでは、aObjects.@countクエリ対象のオブジェクトを表す両方のテーブルが必要であり、非常に醜いSQLが生成されます。ここで試みていることは、それ以上探す必要はありませんbObject

于 2011-02-06T19:54:57.017 に答える