Возможны ли сложные индексы при использовании Core Data?

Я работаю над обучающим приложением в стиле флеш-карты для iOS, которое при загрузке должно получить кучу данных из Core Data. Но данные, которые мне нужны, представляют собой довольно специфическое подмножество сущности, основанное на пользовательских настройках, поэтому существует несколько предикатов, связанных с проверкой эквивалентности. Я считаю, что эти выборки очень медленные, и, основываясь на исследовании SQLite, я думаю, что индекс будет хорошим выбором здесь.

Теперь я понимаю (в основном из прочтения других вопросов о стековом потоке), что SQLite и Core Data - это две разные, в основном ортогональные вещи, которые не следует путать. Но я также понимаю, что вы должны работать с Core Data, чтобы выполнять какую-либо работу с базой данных и настраивать ее; Вы не должны пытаться обходить и работать напрямую с SQLite при оптимизации или проектировании постоянства объектов в вашем приложении.

Но единственное, что я могу найти для индексов в Базовых данных - это один «индексированный» флажок для каждого атрибута в модели. И это просто не та оптимизация, которую я ищу.

Вот запрос на выборку, в настоящее время:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"SKUserItem" inManagedObjectContext:context];
fetchRequest.entity = entity;

NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"next" ascending:YES] autorelease];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

NSMutableArray *predicates = [NSMutableArray arrayWithCapacity:6];
[predicates addObject:[NSPredicate predicateWithFormat:@"next < %f", now() + (60.0*60.0*24.0)]];
[predicates addObject:[NSPredicate predicateWithFormat:@"next > %f", nextOffset]];
[predicates addObject:[NSPredicate predicateWithFormat:@"user == %@", user]];
[predicates addObject:[NSPredicate predicateWithFormat:@"langRaw == %d", lang]];

NSArray *stylePredicates = [NSArray arrayWithObjects:[NSPredicate predicateWithFormat:@"styleRaw == %d", SK_SIMP_AND_TRAD], [NSPredicate predicateWithFormat:@"styleRaw == %d", self.style], nil];
[predicates addObject:[NSCompoundPredicate orPredicateWithSubpredicates:stylePredicates]];

if([self.parts count] == 4 || (self.lang == SK_JA && [self.parts count] == 3))
    ;  // don't have to filter by parts; they're studying all of them
else {
    NSMutableArray *partPredicates = [NSMutableArray arrayWithCapacity:[self.parts count]];
    for(NSString *part in self.parts)
        [partPredicates addObject:[NSPredicate predicateWithFormat:@"partRaw == %d", partCode(part)]];
    [predicates addObject:[NSCompoundPredicate orPredicateWithSubpredicates:partPredicates]];
}

NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates];
fetchRequest.predicate = compoundPredicate;

Таким образом, по сути, эта выборка выполняет сортировку по следующему (время, когда должен быть задан данный элемент) и фильтрует имя пользователя, изучаемый язык, изучаемый стиль (на китайском языке это упрощенный и традиционный) и изучаемые части (написание, тональность , чтение или определение), и только выборка в пределах "следующего" диапазона. Вот краткий список того, что я узнал от настройки и возни с этим:

Он всегда сканирует всю таблицу, или кажется. Несмотря на то, что next индексируется, даже если я заставлю его искать диапазон, который, как я знаю, ничего не даст, для получения выборки все равно требуется несколько секунд.Предикаты, любое количество предикатов, делают это медленным. Если я удаляю некоторые, но не все, это примерно так же медленно. Если я удаляю все предикаты (таким образом нарушая приложение), тогда это происходит намного быстрее.Скорость сильно зависит от количества пользовательских элементов в таблице. Чем больше предметов, тем медленнее. У некоторых людей может быть десятки тысяч предметов, и тогда эта выборка может занять до 10 секунд. Это приводит к неловким паузам в моем приложении.Верхняя граница следующего значения была добавлена не потому, что она нам нужна, а потому, что она немного ускоряет выборку.Если запрос возвращает подмножество свойств в словаре (а не весь управляемый объект), а выборка лениво выполняется быстрее, но все же недостаточно быстро.

Я пришел из Google App Engine здесь, так что я привык к индексам, которые они там предоставляют. По сути, я хочу такой индекс, но применяется к SQLite через Core Data. Я нашел информацию о добавлении индексов в SQLite, какой я хотел бы, но, выполняя такого рода индексацию через Core Data, я не могу найти никакой информации об этом.

Ответы на вопрос(2)

Ваш ответ на вопрос