简体   繁体   English

与我的多对多关系,获取核心数据非常慢?

[英]Core Data fetches are extremely slow with my many-to-many relationships?

I have a Core Data database with 3 entity types, Unit/Department/Document.. 我有一个核心数据数据库,其中包含3种实体类型,单位/部门/文档。

Unit/Department has a one-to many on the Department side, that is, a Unit can have multiple Departments, but each Department can only have one Unit. 部门/部门在部门方面有一对多的关系,即一个部门可以有多个部门,但是每个部门只能有一个部门。

Each Document can be a part of one or more Units and-or Departments, and i need to be able to find document matching a selected Unit or Department. 每个文档可以是一个或多个单位和/或部门的一部分,我需要能够找到与所选单位或部门匹配的文档。 The Unit id could be "1234" and the Department id for that Unit could be "123499". 单位ID可以是“ 1234”,该部门的部门ID可以是“ 123499”。 Notice that the Department id is always the 4 figures of the Unit, and then 2 more describing the Department. 请注意,部门编号始终是单位的4个数字,然后是另外2个描述部门的数字。

So much for the data model, the problem is that when i select a Unit(and no Department), and need to list all the Documents under that Unit, the search should return all documents that belongs to that Unit AND all the documents that that belongs to ALL the departments under that Unit, and that search is taking over 4 seconds with 5000 Documents, I must do something wrong. 对于数据模型来说太多了,问题是当我选择一个部门(没有部门)并且需要列出该部门下的所有文档时,搜索应该返回属于该部门的所有文档以及该部门的所有文档。属于该部门下的所有部门,并且搜索需要花费4秒钟以上的时间来查找5000个文档,所以我必须做错什么。

I am using a NSFetchedResultsController and here are my Predicate. 我正在使用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];

Can I do this in another way ? 我可以用其他方式吗? I was wondering if I could select the Unit instead, and then go through Unit.documents instead, but then i think my FetchController is not needed, and i need to put the results in an Array, and sort them first(which fetches all Entitites, and takes even longer).. 我想知道是否可以选择Unit,然后再通过Unit.documents,但是后来我认为不需要FetchController,我需要将结果放入Array中,然后对它们进行排序(获取所有实体) ,甚至需要更长的时间。..

To make matters worse, i also need to be able to search within the Name attribute of the documents later, and that CONTAINS[cd] makes the search even slower, I unfortunately cannot split the words into a seperate table, because I need to be able to mach words WITHIN words, that is, the user could type "result" and the the search should return all documents which has "result" somewhere in the title, an example could be "NSFetchedResultControllers are cool" 更糟糕的是,我还需要稍后能够在文档的Name属性中进行搜索,而CONTAINS [cd]会使搜索更加缓慢,但是很遗憾,我无法将单词拆分为单独的表,因为我需要可以在单词内处理单词,即用户可以键入“结果”,并且搜索应返回标题中某处具有“结果”的所有文档,例如“ NSFetchedResultControllers很酷”

How can I make that CONTAINS search perform better, right now i have only 5000 docs, but it could also be 20000 or more. 我如何才能使CONTAINS搜索的性能更好,现在我只有5000个文档,但也可能是20000个或更多。

Any good ideas, thoughts ? 有什么好主意,想法吗? I have watched a lot of WWDC Core Data videos, read Core Data performance on the Apple developer site, I really think i have done it the right way, but maybe my model is all wrong, I can see in the SQL debug, that there is a lot of time used on joining tables, and I have tried to figure out how to make that SQL cleaner. 我看了很多WWDC核心数据视频,在Apple开发人员网站上阅读了核心数据性能,我确实认为我做得对,但是也许我的模型是错误的,我可以在SQL调试中看到,在连接表上花了很多时间,我试图弄清楚如何使该SQL更加整洁。

Thank you very much /Jacob 非常感谢/ Jacob

You are right in assuming that CONTAINS and BEGINSWITH are slowing the query down significantly. 您认为CONTAINSBEGINSWITH降低了查询速度,这是正确的。 I have two ideas for you: 我有两个想法给你:

  1. Use indexing (as I am sure you know from the WWDC videos). 使用索引(我确信您从WWDC视频中知道)。 Especially for your text search with CONTAINS this should be a big performance boost. 特别是对于使用CONTAINS进行文本搜索而言,这应该会大大提高性能。

  2. With the specific predicate you mention, I would try using the number property of the id. 对于您提到的特定谓词,我将尝试使用id的number属性。 In your scheme you have already conveniently ordered the ids by unit. 在您的方案中,您已经方便地按单位订购了ID。

The predicate could then be something like this: 谓词可能是这样的:

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];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM