2012-06-23 173 views
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) 

我对读这个不是很熟悉,但它似乎在.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它显然是说,它花了1.4407秒4000行,但不能再9秒我得到的输出称“说完取“(这是一个在[[self fetchedResultsController] performFetch:&error]之后出现的NSLog语句)怎么回事?

回答

2

删除setFetchBatchSize。

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

而且,如果你需要加载的所有属性,添加:

fetchRequest.returnsObjectsAsFaults = NO; 

它会加载每个实体和填充属性。

您可能希望只加载某些属性,所以用它来选择你需要的东西:

fetchRequest.propertiesToFetch = ... 

大功告成。

+0

嗯,我真的不想取所有东西,我是为了测试而做的。实际上,我会有一个谓词,但为了测试的目的,我想知道在没有谓词的情况下获取所有实体需要多长时间(因为谓词耗时过长)。但是,在删除setFetchBatchSize之后,我不再获得数千行SQL日志。但我确实想保留batchSize。 – Snowman

+0

如果你保留它,那么核心数据将不得不解决数以千计的错误,因此你看到的请求。这需要很长时间。 –

+0

但它不应该只在需要时解决故障吗?我的表格每次只显示4个单元格,为什么它立即出现数千个对象的错误? – Snowman