2

我有 2 个实体,A 和 B,它们具有多对多关系。

A 实体有大约 10,000 个对象,B 有大约 20 个对象。

基本上,A 对象可以与一个或多个 B 对象相关,并且 B 对象会跟踪它们所连接的 A 对象。这是通过反向关系设置完成的。

我只是希望返回与 A 对象无关的每个 B 对象。我正在使用的获取是这样的:

NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
[fetch setIncludesPropertyValues:NO];
[fetch setEntity:[NSEntityDescription entityForName:@"B" inManagedObjectContext:context]];
[fetch setPredicate:[NSPredicate predicateWithFormat:@"aObjects.@count == 0"]];
return [context executeFetchRequest:fetch error:nil];

但是,获取执行需要很长时间,大约。30秒。这个我不明白,因为虽然有大量的A对象,但是这个fetch跟他们无关,只需要检查20个B对象。

如果我注释掉谓词以使 fetch 返回所有 B 对象,那么 fetch 非常快,正如您所期望的仅获取 20 个对象。因此,该谓词似乎涉及一些 A 对象并导致它花费很长时间!

任何人都可以解释为什么这需要这么长时间吗?

编辑:

我有 SQL 调试信息,输出如下:

CoreData: sql: SELECT t0.Z_ENT, t0.Z_PK FROM ZTABLEVIEWOBJECT t0 WHERE ((SELECT COUNT(*) FROM ZTABLEVIEWOBJECT t1 JOIN Z_10BOBJECTS t2 ON t1.Z_PK = t2.Z_10AOBJECTS3 JOIN ZTABLEVIEWOBJECT t3 ON t2.Z_12BOBJECTS = t3.Z_PK WHERE (t0.Z_PK = t2.Z_12BOBJECTS) ) = ? AND  t0.Z_ENT = ?) 
CoreData: annotation: sql connection fetch time: 49.4198s
CoreData: annotation: total fetch execution time: 49.4240s for 0 rows.

我应该补充一点,实体 A 和实体 B 都继承(具有父级)一个通用 TableViewObject 实体,该实体拥有两者之间的通用值(例如表视图部分名称和排序名称等)。希望这可以帮助!

4

4 回答 4

4

你可以更换

aObjects.@count == 0

ANY aObjects == nil

它大大减少了我的查询时间(iPhone OS 3.0)。它也适用于!= nil( @count != 0)。

于 2010-03-22T16:42:31.990 回答
3

如果您使用的是 SQLite 存储,则可以打开 SQL 调试日志记录。Core Data 会将它发出的所有 SQL 命令记录到控制台。我发现这对于发现幕后发生的意外事件非常有用。它还将打印出每个 SQL 命令的时间信息!

为此,请双击项目中的可执行文件,转到“参数”选项卡,然后添加一个参数:

-com.apple.CoreData.SQLDebug 1
于 2010-01-04T15:42:44.287 回答
1

如果我对您的理解正确,则这些对象之间存在多对多关系,这可能会导致您的问题。在多对多中,B 和 A 之间有一个连接表,并且该连接表可能会受到重创。我很想知道您的 fetch 正在生成的 SQL。

更新

尝试将谓词更改为“aObjects == nil”,看看会发生什么。因为它是一个多对多关系,这是我能想到的唯一其他谓词,它可能会给你你正在寻找的结果。

于 2010-01-04T16:41:11.003 回答
0

我想这有点晚了,但也许这会帮助遇到这个问题的其他人。反向关系 onbObjects是 in 的属性bObjects并表示为NSSetin bObjects。如果NSSetnil或 中的对象计数NSSet为零,则aObjects与特定的 无关bObject

测试aObjects.@count需要代表要查询的对象的两个表,并且会生成一些非常丑陋的 SQL。您在这里尝试的内容无需再看bObject.

于 2011-02-06T19:54:57.017 回答