gpt4 book ai didi

objective-c - 使用 Core Data 时是否可以使用复杂索引?

转载 作者:技术小花猫 更新时间:2023-10-29 11:13:35 24 4
gpt4 key购买 nike

我正在开发一款 iOS 闪存卡式学习应用程序,该应用程序在加载时需要从 Core Data 中获取大量数据。但我需要的数据是实体的一个相当具体的子集,基于用户设置,所以有多个谓词涉及测试等价性。我发现这些提取速度非常慢,并且根据对 SQLite 的研究,我认为索引是一个不错的选择。

现在,我明白(主要是通过阅读其他 stackoverflow 问题)SQLite 和 Core Data 是两个不同的、基本上正交的东西,不应混淆。但我的理解是,您应该通过 Core Data 进行任何类型的数据库工作和调整;在您的应用程序中优化或设计对象持久性时,您不应尝试绕过 SQLite 并直接使用 SQLite。

但我在 Core Data 中唯一能找到的索引是模型中每个属性的一个“索引”复选框。这只是没有进行我正在寻找的那种优化。

这是获取请求,目前:

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;

所以本质上,这个获取所做的是按下一个(给定项目到期的时间)排序并过滤用户名、正在研究的语言、正在研究的风格(在中文中有简体和繁体)和正在研究的部分(写作、语气、阅读或定义),并且仅在“下一个”范围内获取。这是我从调整和摆弄中学到的东西的简短列表:

  1. 它总是扫描整个表,或者似乎是。虽然 next 已编入索引,但即使我强制它搜索一个我知道不会返回任何内容的范围,它仍然需要几秒钟才能完成提取。
  2. 谓词,任意数量的谓词,都会使它变慢。如果我删除一些但不是全部,它会很慢。如果我删除所有谓词(从而破坏应用程序),那么它会快得多。
  3. 速度在很大程度上取决于表中总共有多少个 UserItem。项目越多,速度越慢。有些人可能拥有数万个项目,而此时此提取可能需要多达 10 秒才能完成。这会导致我的应用出现尴尬的暂停。
  4. 添加下一个值的上限不是因为我们需要它,而是因为它稍微加快了获取速度。
  5. 让查询返回字典中属性的一个子集(而不是整个托管对象)并延迟获取其余部分会更快,但仍然不够快。

我来自这里的 Google App Engine,所以我已经习惯了他们在那里提供的索引。本质上我想要那种索引,但通过 Core Data 应用于 SQLite。我找到了有关在 SQLite 中添加索引的信息,这是我想要的那种,但是通过 Core Data 进行这种索引,我找不到任何相关信息。

最佳答案

您想要的是 Core Data 在 iOS 5.0 及更高版本中支持的复合索引

您可以在 Xcode 中设置它:Entity 检查器有一个 Indexes 部分,或者如果您在代码中创建 NSEntityDescription , 使用 -setCompoundIndexes:.

如果你使用 Xcode,你会在 Indexes 部分添加一行

next,user,langRaw

这样 SQL 就可以为您的查询使用索引。

关于objective-c - 使用 Core Data 时是否可以使用复杂索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8197715/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com