对于我的多对多关系,Core Data 获取速度非常慢?

Posted

技术标签:

【中文标题】对于我的多对多关系,Core Data 获取速度非常慢?【英文标题】:Core Data fetches are extremely slow with my many-to-many relationships? 【发布时间】:2012-06-03 23:19:40 【问题描述】:

我有一个包含 3 种实体类型的核心数据数据库,单位/部门/文档..

Unit/Department在Department端是一对多的,即一个Unit可以有多个Department,但每个Department只能有一个Unit。

每个文档都可以是一个或多个单位和/或部门的一部分,我需要能够找到与所选单位或部门匹配的文档。单位 ID 可以是“1234”,该单位的部门 ID 可能是“123499”。请注意,Department id 始终是 Unit 的 4 位数字,然后是描述 Department 的另外 2 个数字。

对于数据模型来说,问题是当我选择一个单元(并且没有部门)并且需要列出该单元下的所有文档时,搜索应该返回属于该单元的所有文档以及所有属于该单位下所有部门的文档,并且搜索超过 4 秒,包含 5000 个文档,我必须做错事。

我正在使用 NSFetchedResultsController,这是我的谓词。

NSPredicate *predicate;
NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName:@"Document"];   
[req setPropertiesToFetch:[NSArray arrayWithObjects:@"name",@"publisher",@"isFavourite", nil]];
 req.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]]; 
[req setFetchBatchSize:15];
predicate = [NSPredicate predicateWithFormat:@"ANY units.id == %@ || ANY departments.id BEGINSWITH[cd] %@",self.selectedUnit.id,self.selectedUnit.id];

我可以用另一种方式做到这一点吗?我想知道是否可以改为选择 Unit,然后通过 Unit.documents 代替,但后来我认为不需要我的 FetchController,我需要将结果放入一个数组中,然后先对它们进行排序(它会获取所有实体,并且需要更长的时间)..

更糟糕的是,我以后还需要能够在文档的 Name 属性中进行搜索,而 CONTAINS[cd] 使搜索变得更慢,不幸的是我无法将单词拆分到单独的表中,因为我需要能够在单词中匹配单词,也就是说,用户可以输入“结果”并且搜索应该返回标题中某处有“结果”的所有文档,例如“NSFetchedResultControllers 很酷”

我怎样才能使 CONTAINS 搜索性能更好,现在我只有 5000 个文档,但也可能是 20000 个或更多。

有什么好的想法、想法吗?我看过很多 WWDC Core Data 视频,在 Apple 开发者网站上阅读 Core Data 性能,我真的认为我做得对,但也许我的模型全错了,我可以在 SQL 调试中看到,那里在连接表上花费了很多时间,我试图弄清楚如何使 SQL 更清晰。

非常感谢 /雅各布

【问题讨论】:

【参考方案1】:

您正确地假设 CONTAINSBEGINSWITH 正在显着减慢查询速度。我有两个想法给你:

    使用索引(我相信您从 WWDC 视频中知道)。尤其是对于您使用 CONTAINS 进行的文本搜索,这应该会大大提升性能。

    对于您提到的特定谓词,我会尝试使用 id 的 number 属性。在您的方案中,您已经方便地按单位订购了 id。

谓词可能是这样的:

NSNumber *bottom = [NSNumber numberWithInt:[self.selectedUnit.id intValue]*100];
NSNumber *top = [NSNumber numberWithInt:([self.selectedUnit.id intValue]+1)*100];
[NSPredicate predicateWithFormat:
   @"ANY units.id == %@ || ANY (departments.id > %@ AND departments.id < %@)",
   self.selectedUnit.id, bottom, top];

【讨论】:

我已经在我的“name”属性上使用了索引,所以很遗憾我无法获得更多的性能。而且由于我需要在单词中进行搜索,因此我不知道如何才能使搜索变得更好。是否有助于维护一个搜索词表,然后在该表中进行 CONTAINS 搜索?每个实体只有一个单词,因此 CONTAINS 只会搜索有限数量的字符而不是文档的整个“名称”,“名称”最多可以包含 15-20 个单词。谢谢你的例子代码,但“99”只是一个例子,它也可能是“1234HG”,对不起

以上是关于对于我的多对多关系,Core Data 获取速度非常慢?的主要内容,如果未能解决你的问题,请参考以下文章

如何有效地迭代 NSSet (Objective-C) - Core Data 中的多对多关系表示?

使用 Swift 和 Core Data 的多对多附加数据

EF Core 5.0 - 更新 ASP.NET Core Web API 中的多对多实体

EF Core 5.0 中的多对多关系是不是可以配置为仅保留一个导航属性(在一侧)?

使用流利的 api EF Core 5 的多对多关系

Asp.net Core中的多对多实现问题[重复]