「 Product」エンティティのデータベースがあり、およそ 40k ~ 500k のエントリがあります。ユーザーがエンティティのテーブルをスクロールできるようにするビューがあります (デザインが悪いことは知っていますが、それは顧客が望んでいることです)。
「Product」エンティティは次のようになります。
**Product:**
- part_number (string) (indexed)
- list_price (string)
- manufacturer_partNumber (string)
- productDescription (string)
- productID (string)
• inventory (NSManagedObject, 1..n)
- name (string)
- quantity (string)
• manufacturer (NSManagedObject, 1..1)
- name (string)
- manufacturerID (string)
最初に、ソート記述子が設定されたすべてのProductエンティティをNSFetchedResultsController
返す標準的な方法で作成しました。フェッチを高速化するために、すべてのフープを飛び越えました。part_number
- fetchBatchSize
- プロパティのインデックス作成
- クエリを説明
これを行うと、取得を約 3.5 分までしかできませんでした。良くない。
そのため、EXPLAIN QUERY から、エンティティinventory
とmanufacturer
エンティティのフェッチに多くの時間が費やされていることがわかりました。合理的ですが、まだ良くありません。そこで、who ではなく、 Productエンティティの一部のプロパティのみを返すように変更することにしました。
これが私がフェッチしているプロパティですsetPropertiesToFetch
- part_number (string) (indexed)
- list_price (string)
- photo (string)
- productID (string)
at 15でソート記述子が設定されpart_number
ていますfetchBatchSize
。これにより、フェッチ時間が約 40 秒に短縮されます。まだ良くない。
誰かがここで私がセットアップする方法を尋ねることを知っていますNSFetchedResultsController
:
- (NSFetchedResultsController *)fetchedResultsControllerWithCacheName:(NSString*)cacheName {
[NSFetchedResultsController deleteCacheWithName:cacheName];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Product" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"part_number" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:15];
[fetchRequest setResultType:NSDictionaryResultType];
[fetchRequest setReturnsDistinctResults:YES];
[fetchRequest setPropertiesToFetch:@[@"part_number", @"list_price", @"photo", @"productID"]];
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil
cacheName:cacheName];
return theFetchedResultsController;
}
これをスピードアップするために他にできることはありますか?
おそらく本当にハックなアイデアの1つは、NSFetchedResultsControllerである種の遅延読み込みを行うことです(はい、それを処理することになっていることはわかっています)。私はこれを完全に考えていませんが、setFetchLimit
を 100 と言うように設定し、 NSPredicate を使用して最後のpart_number
. これには時間がかかるだけかもしれません。