Объемная вставка основных данных внезапно замедляется до 1/10 скорости

Я выполняю массовую вставку в основные данные. У меня есть объект "человек", и этот объект "человек" имеет отношение под названием "otherPeople", которое представляет собой NSSet of people. При массовой вставке данных из загрузки все было замечательно, пока не прочитали около 10 000 человек, после чего скорость массовой вставки снизилась до ползания. Я сохраняю и сбрасываю свой NSManagedObjectContext каждые 500 вставок.

Если я закомментирую часть, которая вставляет отношения «otherPerson», массовая вставка выполняется быстро на протяжении всей загрузки. parseJSON вызывается пакетами по 500 словарей JSONKit.

Есть идеи, что может быть причиной этого? Возможные решения?

Код:

- (NSArray*) getPeople:(NSArray*)ids
{
    NSFetchRequest* request = [[[NSFetchRequest alloc] init] autorelease];
    NSEntityDescription* entityDescription = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:context];
    [request setEntity:entityDescription];
    [request setFetchBatchSize:ids.count];

    //Filter by array of ids
    NSPredicate* predicate = [NSPredicate predicateWithFormat:@"externalId IN %@", ids];
    [request setPredicate:predicate];

    NSError* _error;
    NSArray* people = [context executeFetchRequest:request error:&_error];

    return people;
}

- (void) parseJSON:(NSArray*)people
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    NSMutableArray* idsToFetch = [NSMutableSet setWithCapacity:CHUNK_SIZE * 3];
    NSMutableDictionary* existingPeople = [NSMutableDictionary dictionaryWithCapacity:CHUNK_SIZE * 3];

    // populate the existing people dictionary first, that way we know who is already in the context without having to do a fetch for each person in the array (externalId IS indexed)
    for (NSDictionary* personDictionary in people)
    {
        // uses JSON kit to parse out all the external ids...
        [PersonJSON addExternalIdsToArray:idsToFetch fromDictionary:personDictionary];
    }

    // see above code for getPeople implementation...
    NSArray* existingPeopleArray = [self getPeople:idsToFetch];
    for (Person* p in existingPeopleArray)
    {
        [existingPeople setObject:p forKey:p.externalId];
    }

    for (NSDictionary* personDictionary in people)
    {
        NSString* externalId = [personDictionary objectForKey:@"PersonId"];
        Person* person = [existingPeople objectForKey:externalId];

        if (person == nil)
        {
            // the person was not in the context, make a new person in the context
            person = [[self newPerson] autorelease];
            person.ancestryId = externalId;
            [existingPeople setObject:person forKey:person.externalId];
        }

        // use JSON kit to populate the core data object...
        [PersonJSON populatePerson:person withDictionary:personDictionary inContext:[self context]];

        // these are just objects that contain an externalId, showing that the link hasn't been setup yet
        for (UnresolvedOtherPerson* other in person.unresolvedOtherPeople)
        {
            Person* relatedPerson = [existingPeople objectForKey:other.externalId];

            if (relatedPerson == nil)
            {
                relatedPerson = [[self newPerson] autorelease];
                relatedPerson.externalId = other.externalId;
                [existingPeople setObject:relatedPerson forKey:relatedPerson.externalId];
            }

            // add link - if I comment out this line, everything runs very fast
            // if I don't comment out, things slow down gradually and then exponentially
            [person addOtherPersonsObject:relatedPerson];
        }

        self.downloaded++;
    }

    [pool drain];
}
5
задан jjxtra 23 August 2011 в 15:37
поделиться