核心数据performance:对更多对多关系的预测

使用SQL数据存储,我有这样一个模型:

类别< – >>项目

collections< – >>项目

品牌< – >>项目

每个左侧的实体都有一个多对多的关系,这个关系命名为Item到Item实体。 每一个分别与一个项目关系类别收集 品牌品牌相反。

我想用至less一个与特定集合和类别相关的项目获取所有品牌对象。 在自然语言中,我需要具有特定类别和特定集合的所有品牌的商品。

给定对象Category * myCategoryCollection * myCollection ,我用这种方式在Brand实体上构build一个谓词:

NSPredicate *myPredicate = [NSPredicate predicateWithFormat:@"(ANY items.category == %@) AND (ANY items.collection == %@)",myCategory,myCollection]; 

我得到正确的结果。 问题是性能。 太慢了! 我简化了三个层次的问题! 我们来考虑iOS多级别目录中的四个级别:应用程序显示可用类别,用户select类别,应用程序显示该类别中的集合,用户select集合,应用程序显示该集合中的品牌(以及已select的类别),用户select一个品牌,该应用程序显示在该品牌,集合和类别的材料…

说实话,我使用NSCompoundPredicate把每个用户的select放在子类中,dynamic构build最终的谓词。 但这个问题的目的并不重要。

在sql数据存储中, Item实体有超过30,000个(30k)的对象,而使用AND之间的关系非常缓慢(在上面的例子中,我注意到7-10秒的滞后时间来显示品牌)。

我会尽力:

– 从类别,collections品和品牌实体中删除物品关系

– 在物品实体上,将类别collections 品牌品牌关系replace为“category_id”,“collection_id”和“brand_id”等属性上的提取属性。

– 使用关键path或谓词来获取品牌而不使用多对多的关系。

在我开始破坏和重塑过去6个月的整个工作之前,你有什么build议吗? 🙂

谢谢!

颠倒你正在寻找的逻辑。

你不是在寻找一个具有一定类别和特定品牌的品牌, 您正在寻找具有X类别和Ytypes集合的物品实体。一旦您拥有该物品,您就可以为其品牌提出要求:

 id myCategory = ...; id myCollection = ...; NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Item"]; [request setPredicate:[NSPredicate predicateWithFormat:@"category == %@ && collection == %@", myCategory, myCollection]]; NSError *error = nil; NSArray *itemArray = [moc executeFetchRequest:request error:&error]; NSAssert2(!error || itemArray, @"Error fetching items: %@\n%@", [error localizedDescription], [error userInfo]); NSArray *brands = [itemArray valueForKey:@"brand"]; return brands; 

更新

Item就像在你的问题中一样,是一个关系另一端的实体。 -valueForKey:将通过一系列的项目,并获得关系的另一端品牌实体,并给你回品牌arrays。 你不需要添加任何东西,甚至没有财产,因为它将通过KVC访问,并将“只是工作”。

这将根据您的要求为您提供最有效的检索。 由于Item在这些关系的每一个的许多方面,它将持有外键,因此SQL不需要跨越表的边界,因此应该是非常快的。

唯一的其他select,我不推荐它,但你可以玩来自类别和集合的集合,并从一个可变的集合中获得一个联盟。 每次我对这个方向进行实验的时候,都要比数据库慢一些。 在我看来,这种逻辑最好在数据库层面完成。