2

Core Data アプリケーションに 2000 レコードを挿入すると、パフォーマンスに問題があります。

データはサーバーから大きな JSON ファイルとしてダウンロードされ、JSON ディクショナリに解析されます。これはすべて問題なく、ディクショナリを渡す時間は何もありません...

問題は、データベースへの各挿入に時間がかかることです。

インポート中に、メモリを抑えるために 100 ドキュメントごとにコンテキストを保存します。最初のドキュメントの保存には 0.005434 ミリ秒かかり、最後のドキュメントの保存には 0.039297 ミリ秒かかります。

undomanager が nil に設定された完全に新しい ManagedContext を使用して、このすべてのインポートを別のスレッドで実行しています。

これは、辞書内のすべてのドキュメントを実行するループです

    NSArray *docs = [docsData objectForKey:@"docs"];
    for(NSDictionary *doc in docs){
        if(counter++ % 100){
            [context save:nil];
        }
        NSDate *start = [NSDate date];
        [Document documentWithDictionary:doc lastModifiedDate:[NSDate date] inLevels:nil inManagedObjectContext:context];
        NSDate *end = [NSDate date];

        NSLog(@"time used pr doc = %f",[end timeIntervalSinceDate:start]);
    }
    [context save:nil];

そして、ここにドキュメントを挿入するコードがあります

     NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName:@"Document"];
    req.predicate = [NSPredicate predicateWithFormat:@"id = %@", [data valueForKey:@"id"]];
    NSArray *matches = [context executeFetchRequest:req error:&error];

    if(matches){    
        if([matches count]){
            document = [matches lastObject];
        }else {
            document = [NSEntityDescription insertNewObjectForEntityForName:@"Document" inManagedObjectContext:context];
        }
   }

挿入に時間がかかる理由について、誰かが光を当てることができますか?

シミュレーターでは、ドキュメントの使用時間はほぼ一定ですが、電話ではそうではありませんか?

これは小さな問題かもしれませんが、データベースには 2000 から 30000 のレコードを保持できるため、これは実際には大規模なインポートの要因になります..

どうもありがとう :)

/ジェイコブ

アップデート - - -

データベースへの挿入のみを実行した後、つまり、既存のレコードを取得せずに、これらは時間です..

フェッチあり:

1100 ドキュメント - 54.6 秒

2349 ドキュメント - 194.9 秒

1872 ドキュメント - 222.1s

フェッチなし。

1100 ドキュメント - 34.4 秒

2349 ドキュメント - 74.19 秒

1872 ドキュメント - 59.1 秒

したがって、結論は、ますます時間がかかるドキュメントの量が増えている私のフェッチ要求であるということです..しかし、それも理にかなっています:)なぜ私が以前にそれを考えなかったのかわかりません...だから今解決策は、同期が最初のものであるかどうかを確認し、既存のドキュメントをフェッチせずにドキュメントをインポートすることです。

/ジェイコブ

4

1 に答える 1

0

あなたのコードに基づいて、問題は何かを挿入することとは何の関係もありません。save メソッドを呼び出すまで、実際には何もデータベースに永続化されません。「...ドキュメントを挿入するコード」は、documentsWithDictionary:lastModifiedDate:inLevels:inManagedObjectContext: メソッドのコードであると想定しています。ここには実際には何も挿入していませんが、メモリ内に新しい ManagedObject を作成しています。ただし、これを行うたびにデータベースにクエリを実行しています。データベース内のレコードの数が増えると、クエリが指定された ID のレコードを見つけるのに少し時間がかかる場合があります。

Apple は、大規模なデータ セットを効率的にインポートするためのいくつかの優れた方法を概説しています。 TP40003174-SW1

特に、「効率的に検索または作成を実装する」を読みたいと思うでしょう。彼らのガイドラインに従って、データベースの読み取りを、レコードのバッチごとに 1 回、またはインポートするデータ セット全体に対して 1 回に制限できます。

于 2012-05-18T15:59:33.437 に答える