1

「 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

  1. fetchBatchSize
  2. プロパティのインデックス作成
  3. クエリを説明

これを行うと、取得を約 3.5 分までしかできませんでした。良くない。

そのため、EXPLAIN QUERY から、エンティティinventorymanufacturerエンティティのフェッチに多くの時間が費やされていることがわかりました。合理的ですが、まだ良くありません。そこで、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. これには時間がかかるだけかもしれません。

4

0 に答える 0