Ios 使用子查询高效地获取CoreData

Ios 使用子查询高效地获取CoreData,ios,sqlite,core-data,subquery,relationship,Ios,Sqlite,Core Data,Subquery,Relationship,我遇到了一个iOS核心数据性能问题 假设我们有两个类:“Class_A”和“Class_B”。它们都有自己的ID,并且彼此之间有一对一的关系 现在让我们假设我正在从web下载数据,该数据允许我创建这些类(数据包含类A和B的id,以及关于它们之间关系的信息)。例如: “将有id为1的类_A的实例” “将有id为2的类_A的实例” “将有id为3的类_A的实例” “将有id为10的类_B的实例” “将有id=11的类_B的实例” “将有id为12的类_B的实例” “id=1的类_A将与id=12

我遇到了一个iOS核心数据性能问题

假设我们有两个类:“Class_A”和“Class_B”。它们都有自己的ID,并且彼此之间有一对一的关系

现在让我们假设我正在从web下载数据,该数据允许我创建这些类(数据包含类A和B的id,以及关于它们之间关系的信息)。例如:

  • “将有id为1的类_A的实例”
  • “将有id为2的类_A的实例”
  • “将有id为3的类_A的实例”
  • “将有id为10的类_B的实例”
  • “将有id=11的类_B的实例”
  • “将有id为12的类_B的实例”
  • “id=1的类_A将与id=12的类_B连接”
  • “id=2的类_A将与id=11的类_B连接”
  • “id=3的类_A将与id=10的类_B连接”
因为所有这些信息都可以以随机顺序获得(例如,关于X和Y类之间的连接的信息可以在关于X和Y类存在的信息之前下载),所以我使用了另一种实体:关系

关系包含两个字段:class_A_id和class_b_id

每次我收到关于ClassA和ClassB之间关系的数据时,我都会创建具有相应属性值的关系实体实例

每过一段时间,我都会迭代“关系”实体的所有实例,并尝试创建如下适当的关系:

SELECT * from 'Relationship' where
    (SELECT * from 'ClassA' where id == class_A_id).count == 1
  AND
    (SELECT * from 'ClassB' where id == class_B_id).count == 1
  • 获取“关系”实体的所有实例
  • 对于每个获取的关系,根据Relationsip中存储的“class_A_id”和“class_B_id”id获取ClassA和ClassB的实例
  • 如果类A和类B的实例都存在,则在它们之间创建关系
  • 从CoreData中删除实例关系
  • 在实现了这个算法之后,我发现它在使用核心数据中数量相当少的对象时效果很好。 问题是我存储了数千个“关系”实体(关于它们的信息首先被下载),而关于“ClassA”和“ClassB”存在的信息下载的频率较低

    结果是,每次我尝试使用“关系”实体创建关系时,我都会获取数千个包含不存在的类id的对象

    因此,我对这个问题的解决方案是增强建议算法的第一步:

    与获取CoreData中的所有关系不同,只获取包含系统中存在的类id的关系

    在SQL中,它可能看起来像这样:

    SELECT * from 'Relationship' where
        (SELECT * from 'ClassA' where id == class_A_id).count == 1
      AND
        (SELECT * from 'ClassB' where id == class_B_id).count == 1
    

    我的问题是-如何在CoreData中实现这样的查询?在那里使用子查询?是的-怎么做?:)

    如果我理解正确,如果您不想对模型进行太多修改,您有两个选择:

    • 第一个选项:修改请求流程,只请求关于您已经拥有的实体的关系,如果您没有那么多类型A、B的实体,这可以很容易地完成。否则,实现某种“增量”,这将避免有数千个您不需要的关系(除非您出于其他目的需要它)
    • 第二种选择:当您下载项目时,我认为这是一个后台过程,在这种情况下,我会立即在其中进行检查,而不是不时进行批处理。例如,在下载关系时,检查是否已经有A或B,并将关系表标记为完整或不完整(可能添加两个属性aExists bExists)。实体A一进来,就把关系中的所有实体都标记为aExists,B也一样,这是一个普通的获取请求,其中类A\U id存在。然后,批处理可以轻松地扫描并仅获取标记为完成的实体,并创建关系。你必须实现一点逻辑,但在我看来事情会变得更快
    新的关系将是:

    Relationships {
      class_A_id,
      class_B_id,
      classAexists BOOL,
      classBexists BOOL,
      batchRelationshipCreated BOOL,
    }
    

    无论如何,您都可以实现这两个选项:-)

    您是否可以放弃关系实体,只创建ClassA和ClassB的实例,并通过它们的关系将它们链接在一起?您可以向这些实体添加一个属性,以指示它是占位符而不是完全填充的实体?您还可以模仿SQL方式:当您收到类X和类Y时,您可以根据关系进行检查。当你们收到关系数据时,你们可以对照Class_A和Class_B进行检查。但AE的建议可能效果更好。好吧,正如你们可能猜到的,我的实际应用程序中的模型有点复杂——类“ClassA”和“ClassB”的属性比“id”多,填充这些属性所需的数据不会出现在只包含它们之间关系的web响应中。由于我的应用程序的结构,我不能创建这些分类的“假”实体(只填充“id”字段),我只需要在我有关于它们的完整信息时创建它们。为了更清楚地提出问题,我简化了我的问题