Каков более эффективный способ сортировки и фильтрации основных данных?

Предполагая, что у меня есть объект Podcast, у которого есть много Эпизодов, я не понимаю, какой из них будет предпочтительным вариантом для отбора и сортировки:

// Always work with the relationship property
- (NSSet*)unfinishedEpisodes {
  NSArray* episodes = self.episodes.allObjects;

  NSPredicate* predicate = [NSPredicate predicateWithBlock:^BOOL(PodcastEpisode* episode, NSDictionary* bindings) {
    return !episode.isFinished;
  }];

  NSArray* unfinishedEpisodes = [episodes filteredArrayUsingPredicate:predicate];

  return [NSSet setWithArray:unfinishedEpisodes];
}

- (NSArray*)unfinishedEpisodesSortedByAge {
  NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:YES];

  return [self.unfinishedEpisodes.allObjects sortedArrayUsingDescriptors:sortDescriptors];
}

или же

// Fetch specific sets of data as needed
- (NSArray*)unfinishedEpisodes:(NSArray*)sortDescriptors {  
  NSFetchRequest* fetch = [[NSFetchRequest alloc] initWithEntityName:@"Episode"];

  NSPredicate* predicate = [NSPredicate predicateWithFormat:@"podcast == %@ AND playcount == 0", self];
  fetch.predicate = predicate;

  fetch.sortDescriptors = sortDescriptors;

  NSArray* results = [KRTDataManager.sharedManager.mainObjectContext executeFetchRequest:fetch error:nil];

  return results;
}

- (NSArray*)unfinishedEpisodesSortedByAge {
  NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:YES];

  return [self unfinishedEpisodes:@[ sortDescriptor ]];
}

Часть меня, которая будет делать как можно больше в SQL, будет думать, что вариант 1 труднее думать, но лучше, но большая часть того, что я читал, указывает на то, что использование эпизодов (NSSet*) становится чрезвычайно дешевым, когда объект подкаста входит в существование. Мое понимание того, как сбои данных Core обрабатываются в этих ситуациях, довольно шатко, и я понимаю, что данные Core не следует реально сравнивать с базой данных SQL. Просто основываясь на том, как устроены эти два варианта, я думаю, что есть некоторая выгода для выпекания предиката и дескрипторов сортировки прямо в выборку; но, возможно, этого недостаточно, чтобы компенсировать выгоды, которые дают отношения, предоставляемые отношениями.

Благодарю.

1 ответ

Решение

Первый код будет неэффективным при работе с большими наборами результатов, так как он работает в объектах памяти. Все объекты должны быть загружены в память, поэтому, если их там еще нет, они будут загружаться один за другим по мере возникновения неисправностей.

Второй код будет делать все на стороне SQL и даст вам уже отфильтрованные и отсортированные результаты. CoreData также использует внутреннее кэширование для оптимизации таких запросов, поэтому я бы предпочел эту опцию, если эпизоды еще не загружены где-то еще. Включите отладку CoreData, чтобы увидеть, как будут выглядеть SQL-запросы. Уже есть ответ, как это сделать.

Другие вопросы по тегам