6

我正在运行一个非常基本的 NSFetchRequest 来获取实体 MessageObject。我只有 2000 个消息对象,我想全部检索它们。但是,由于某些奇怪的原因,获取请求需要超过 10 秒!

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"MessageObject" inManagedObjectContext:appDelegate.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort= [[NSSortDescriptor alloc] initWithKey:@"createDate" ascending:NO selector:@selector(compare:)];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:5];

就是这样,这就是我的获取请求。我什至没有使用谓词,它需要超过 10 秒。我对可能导致这种情况的原因一无所知。如果有人有任何想法或起点,请分享。

我也尝试过启用 SQLite 调试日志 ( -com.apple.CoreData.SQLDebug 1),但我只是从这个简单的提取中获得了数千行输出。这正常吗?

 2012-06-22 19:39:59.171 myapp[81825:15e03] about to execute fetch
 2012-06-22 19:39:59.172 myapp[81825:15e03] CoreData: sql: SELECT 0, t0.Z_PK FROM ZMBNOTEOBJECT t0 ORDER BY t0.ZCREATEDATE DESC
 2012-06-22 19:39:59.178 myapp[81825:15e03] CoreData: annotation: sql connection fetch time: 0.0061s
 2012-06-22 19:39:59.179 myapp[81825:15e03] CoreData: annotation: total fetch execution time: 0.0067s for 2052 rows.
 2012-06-22 19:39:59.179 myapp[81825:15e03] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZAUTHOREMAIL, t0.ZAUTHORNAME, t0.ZCREATEDATE, t0.ZISGLOBAL, t0.ZISLOCKED, t0.ZISNEW, t0.ZISPENDINGDELETE, t0.ZISPENDINGLIKE, t0.ZISPENDINGREAD, t0.ZISPENDINGSYNC, t0.ZLASTUPDATED, t0.ZLOCALLYMODIFIEDDATE, t0.ZMAINIDEA, t0.ZMETALASTUPDATED, t0.ZNOTEID, t0.ZNUMBEROFCHILDREN, t0.ZPARENTAUTHOREMAIL, t0.ZPARENTNOTEID, t0.ZROOTAUTHOREMAIL, t0.ZROOTNOTEID, t0.Z4PENDINGADDNOTES, t0.Z4PENDINGREMOVENOTES FROM ZMBNOTEOBJECT t0 WHERE  t0.Z_PK IN  (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)  ORDER BY t0.ZCREATEDATE DESC LIMIT 15
 2012-06-22 19:39:59.180 myapp[81825:15e03] CoreData: annotation: sql connection fetch time: 0.0008s
 2012-06-22 19:39:59.181 myapp[81825:15e03] CoreData: annotation: total fetch execution time: 0.0018s for 15 rows.
 2012-06-22 19:39:59.182 myapp[81825:15e03] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZAUTHOREMAIL, t0.ZAUTHORNAME, t0.ZCREATEDATE, t0.ZISGLOBAL, t0.ZISLOCKED, t0.ZISNEW, t0.ZISPENDINGDELETE, t0.ZISPENDINGLIKE, t0.ZISPENDINGREAD, t0.ZISPENDINGSYNC, t0.ZLASTUPDATED, t0.ZLOCALLYMODIFIEDDATE, t0.ZMAINIDEA, t0.ZMETALASTUPDATED, t0.ZNOTEID, t0.ZNUMBEROFCHILDREN, t0.ZPARENTAUTHOREMAIL, t0.ZPARENTNOTEID, t0.ZROOTAUTHOREMAIL, t0.ZROOTNOTEID, t0.Z4PENDINGADDNOTES, t0.Z4PENDINGREMOVENOTES FROM ZMBNOTEOBJECT t0 WHERE  t0.Z_PK IN  (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)  ORDER BY t0.ZCREATEDATE DESC LIMIT 15
 2012-06-22 19:39:59.186 myapp[81825:15e03] CoreData: annotation: sql connection fetch time: 0.0042s
 2012-06-22 19:39:59.187 myapp[81825:15e03] CoreData: annotation: total fetch execution time: 0.0049s for 15 rows.
 2012-06-22 19:39:59.187 myapp[81825:15e03] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZAUTHOREMAIL, t0.ZAUTHORNAME, t0.ZCREATEDATE, t0.ZISGLOBAL, t0.ZISLOCKED, t0.ZISNEW, t0.ZISPENDINGDELETE, t0.ZISPENDINGLIKE, t0.ZISPENDINGREAD, t0.ZISPENDINGSYNC, t0.ZLASTUPDATED, t0.ZLOCALLYMODIFIEDDATE, t0.ZMAINIDEA, t0.ZMETALASTUPDATED, t0.ZNOTEID, t0.ZNUMBEROFCHILDREN, t0.ZPARENTAUTHOREMAIL, t0.ZPARENTNOTEID, t0.ZROOTAUTHOREMAIL, t0.ZROOTNOTEID, t0.Z4PENDINGADDNOTES, t0.Z4PENDINGREMOVENOTES FROM ZMBNOTEOBJECT t0 WHERE  t0.Z_PK IN  (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)  ORDER BY t0.ZCREATEDATE DESC LIMIT 15
 2012-06-22 19:39:59.188 myapp[81825:15e03] CoreData: annotation: sql connection fetch time: 0.0008s
 2012-06-22 19:39:59.189 myapp[81825:15e03] CoreData: annotation: total fetch execution time: 0.0014s for 15 rows.
... (thousands of more lines similar to above)

我对阅读这篇文章不是很熟悉,但它似乎在 0.0067 秒内获取了 2052 行。那么为什么在那之后它继续做更多的事情呢?如果完成获取行,请求不应该完成吗?是数据有问题还是什么?

此外,我已经删除了 setFetchBatchSize - 它摆脱了数千行,但获取请求仍然需要很长时间。这是我得到的输出:

2012-06-22 20:07:25.316 myapp[8927:707] about to execute fetch
 2012-06-22 20:07:25.322 myapp[8927:707] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZAUTHOREMAIL, t0.ZAUTHORNAME, t0.ZCREATEDATE,t0.ZISLOCKED, t0.ZISNEW, t0.ZISPENDINGDELETE, t0.ZISPENDINGSYNC, t0.ZLASTUPDATED, t0.ZLOCALLYMODIFIEDDATE, t0.ZMAINIDEA, t0.ZMETALASTUPDATED, t0.ZNOTEID, t0.ZNUMBEROFCHILDREN, t0.ZPARENTAUTHOREMAIL, t0.ZPARENTNOTEID, t0.ZROOTAUTHOREMAIL, t0.ZROOTNOTEID, t0.Z4PENDINGADDNOTES, t0.Z4PENDINGREMOVENOTES FROM ZMBNOTEOBJECT t0 ORDER BY t0.ZCREATEDATE DESC
 2012-06-22 20:07:26.758 myapp[8927:707] CoreData: annotation: sql connection fetch time: 1.0891s
 2012-06-22 20:07:26.763 myapp[8927:707] CoreData: annotation: total fetch execution time: 1.4407s for 4000 rows.
 2012-06-22 20:07:35.967 myapp[8927:707] finished fetching

奇怪的是,在 20:07:26.763,它显然表示 4000 行需要 1.4407 秒,但不是再过 9 秒,我得到的输出是“完成获取”(这是一个出现在 NSLog 之后的语句[[self fetchedResultsController] performFetch:&error])这是怎么回事那?

4

1 回答 1

2

删除 setFetchBatchSize。

如果您的意图是一次加载所有内容,只需将其删除。

此外,如果您需要加载所有属性,请添加:

fetchRequest.returnsObjectsAsFaults = NO;

它将加载每个实体并填充属性。

您可能只想加载某些属性,因此使用它来选择您需要的内容:

fetchRequest.propertiesToFetch = ...

你完成了。

于 2012-06-23T00:54:20.610 回答