2

ユニット/部門/ドキュメントの 3 つのエンティティ タイプを持つコア データ データベースがあります。

ユニット/部門は、部門側で 1 対多です。つまり、ユニットは複数の部門を持つことができますが、各部門は 1 つのユニットしか持つことができません。

各ドキュメントは、1 つ以上のユニットまたは部門の一部である可能性があり、選択したユニットまたは部門に一致するドキュメントを検索できる必要があります。ユニット ID は「1234」であり、そのユニットの部門 ID は「123499」である可能性があります。Department id は常に Unit の 4 つの数字であり、次に Department を表す 2 つの数字であることに注意してください。

データモデルに関しては、問題は、ユニットを選択し(部門なしで)、そのユニットの下にあるすべてのドキュメントをリストする必要がある場合、検索はそのユニットに属するすべてのドキュメントと、そのユニットに属するすべてのドキュメントを返す必要があることです。そのユニットの下のすべての部門に属しており、その検索は 5000 のドキュメントで 4 秒以上かかっています。何か間違ったことをしなければなりません。

私は NSFetchedResultsController を使用しています。これが私の述語です。

NSPredicate *predicate;
NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName:@"Document"];   
[req setPropertiesToFetch:[NSArray arrayWithObjects:@"name",@"publisher",@"isFavourite", nil]];
 req.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]]; 
[req setFetchBatchSize:15];
predicate = [NSPredicate predicateWithFormat:@"ANY units.id == %@ || ANY departments.id BEGINSWITH[cd] %@",self.selectedUnit.id,self.selectedUnit.id];

これを別の方法で行うことはできますか? 代わりに Unit を選択し、代わりに Unit.documents を通過できるかどうか疑問に思っていましたが、FetchController は必要ないと思います。結果を配列に入れて、最初に並べ替える必要があります (これにより、すべてのエンティティがフェッチされます)。 、さらに時間がかかります)。

さらに悪いことに、後でドキュメントの Name 属性内を検索できるようにする必要があり、CONTAINS[cd] を使用すると検索がさらに遅くなります。残念ながら、単語を別のテーブルに分割することはできません。つまり、ユーザーが「result」と入力すると、タイトルのどこかに「result」が含まれるすべてのドキュメントが返されます。たとえば、「NSFetchedResultControllers are cool」のようになります。

CONTAINS 検索のパフォーマンスを向上させるにはどうすればよいですか。現在、ドキュメントは 5000 しかありませんが、20000 以上になる可能性もあります。

良いアイデア、考えはありますか?WWDC Core Data のビデオをたくさん見たり、Apple 開発者サイトで Core Data のパフォーマンスを読んだりしました。本当に正しい方法で行ったと思いますが、モデルがすべて間違っている可能性があります。SQL デバッグで確認できます。テーブルの結合に多くの時間が使用されているため、その SQL をよりクリーンにする方法を見つけようとしました。

どうもありがとう/ジェイコブ

4

1 に答える 1

0

あなたはそれを想定していてCONTAINSBEGINSWITHクエリを大幅に遅くしています。私はあなたのために2つのアイデアを持っています:

  1. インデックスを使用します(WWDCビデオからご存知のとおり)。特にこれを使用したテキスト検索でCONTAINSは、パフォーマンスが大幅に向上するはずです。

  2. あなたが言及した特定の述語で、私はidのnumberプロパティを使用してみます。あなたのスキームでは、あなたはすでにユニットごとにIDを便利に注文しています。

その場合、述語は次のようになります。

NSNumber *bottom = [NSNumber numberWithInt:[self.selectedUnit.id intValue]*100];
NSNumber *top = [NSNumber numberWithInt:([self.selectedUnit.id intValue]+1)*100];
[NSPredicate predicateWithFormat:
   @"ANY units.id == %@ || ANY (departments.id > %@ AND departments.id < %@)",
   self.selectedUnit.id, bottom, top];
于 2012-06-04T08:17:14.330 に答える