Я работаю над обучающим приложением в стиле флеш-карты для iOS, которое при загрузке должно получить кучу данных из Core Data.Но данные, которые мне нужны, представляют собой довольно специфическое подмножество сущности, основанное на пользовательских настройках, поэтому существует несколько предикатов, связанных с проверкой эквивалентности.Я считаю, что эти выборки очень медленные, и, основываясь на исследовании SQLite, я думаю, что индекс будет хорошим выбором здесь.
Теперь я понимаю (в основном из прочтения других вопросов о стековом потоке), что SQLite и CoreДанные - это две разные, в основном ортогональные вещи, которые не следует путать.Но я также понимаю, что вы должны работать с 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, я не могу найти никакой информации об этом.