0

我正在处理一个可以从这里下载的非常小的示例项目。我正在尝试做的是调试为什么在我自己的项目中获取需要这么长时间,但我已经将此项目用作一种基准。我已-com.apple.CoreData.SQLDebug 1在我的方案中启用,因此我可以看到哪些命令正在通过我的提取发送到 SQLite 存储。

首先,在 AppDelegate 中,我只是将第一部分(正在创建银行的地方)包装在一个 for 循环中以创建 1000 个对象。他们注释掉来自 AppDelegate 的获取请求。

然后,在 FBCFMasterViewController 中,那里有一个获取请求。在保存 1000 个项目并将它们提取到 NSFetchedResultsController 后运行应用程序时,您将看到数千条类似于以下内容的输出行:

2012-06-23 09:16:30.374 FailedBankCD[90166:fb03] CoreData: annotation: sql connection fetch time: 0.0004s
2012-06-23 09:16:30.375 FailedBankCD[90166:fb03] CoreData: annotation: total fetch execution time: 0.0009s for 1 rows.
2012-06-23 09:16:30.375 FailedBankCD[90166:fb03] CoreData: annotation: fault fulfilled from database for : 0xc3e9060 <x-coredata://60E5B64A-83AB-4E6A-BEAD-5FFF50DB7F66/FailedBankDetails/p823>
2012-06-23 09:16:30.376 FailedBankCD[90166:fb03] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZCLOSEDATE, t0.ZUPDATEDATE, t0.ZZIP, t0.ZINFO FROM ZFAILEDBANKDETAILS t0 WHERE  t0.Z_PK = ?

我猜这是因为 sortDescriptor 是用关键 details.closeDate 初始化的,这是一个关系,所以当它按该属性排序时,它必须获取每个对象的错误,导致出现数千行输出。

所以我更改了 sortDescriptor 以对属性进行排序city,这次运行时,我得到以下输出:

2012-06-23 08:53:04.924 FailedBankCD[89564:fb03] CoreData: sql: SELECT 0, t0.Z_PK FROM ZFAILEDBANKINFO t0 ORDER BY t0.ZCITY DESC
2012-06-23 08:53:04.929 FailedBankCD[89564:fb03] CoreData: annotation: sql connection fetch time: 0.0049s
2012-06-23 08:53:04.930 FailedBankCD[89564:fb03] CoreData: annotation: total fetch execution time: 0.0059s for 1009 rows.
2012-06-23 08:53:04.936 FailedBankCD[89564:fb03] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZCITY, t0.ZNAME, t0.ZSTATE, t0.ZDETAILS FROM ZFAILEDBANKINFO t0 WHERE  t0.Z_PK IN  (?,?,?,?,?,?,?,?,?,?)  ORDER BY t0.ZCITY DESC LIMIT 10
2012-06-23 08:53:04.938 FailedBankCD[89564:fb03] CoreData: annotation: sql connection fetch time: 0.0013s
2012-06-23 08:53:04.939 FailedBankCD[89564:fb03] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZCLOSEDATE, t0.ZUPDATEDATE, t0.ZZIP, t0.ZINFO FROM ZFAILEDBANKDETAILS t0 WHERE  t0.ZINFO IN  (?,?,?,?,?,?,?,?,?,?)  
2012-06-23 08:53:04.971 FailedBankCD[89564:fb03] CoreData: annotation: sql connection fetch time: 0.0318s
2012-06-23 08:53:04.972 FailedBankCD[89564:fb03] CoreData: annotation: total fetch execution time: 0.0326s for 10 rows.
2012-06-23 08:53:04.973 FailedBankCD[89564:fb03] CoreData: annotation: Prefetching with key 'details'.  Got 10 rows.
2012-06-23 08:53:04.974 FailedBankCD[89564:fb03] CoreData: annotation: total fetch execution time: 0.0372s for 10 rows.

我不再重复数千行输出,这似乎是预期的输出。但是,如果我再次运行,甚至不修改任何内容,我将再次获得类似于以下内容的数千行输出:

2012-06-23 09:19:31.263 FailedBankCD[90216:fb03] CoreData: annotation: sql connection fetch time: 0.0006s
2012-06-23 09:19:31.264 FailedBankCD[90216:fb03] CoreData: annotation: total fetch execution time: 0.0010s for 20 rows.
2012-06-23 09:19:31.264 FailedBankCD[90216:fb03] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZCITY, t0.ZNAME, t0.ZSTATE, t0.ZDETAILS FROM ZFAILEDBANKINFO t0 WHERE  t0.Z_PK IN  (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)  ORDER BY t0.ZCITY DESC LIMIT 20

这是奇怪的行为,不是吗?任何人都可以快速复制并解释发生了什么,以及为什么我会得到数千行输出吗?

4

1 回答 1

1

close_date并且city没有被索引,这解释了成千上万的查询,并且可能性能低下。对于运行之间的差异,我敢打赌您正在使用的缓存:

NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                    managedObjectContext:managedObjectContext sectionNameKeyPath:nil
                                               cacheName:@"Root"];
于 2012-06-24T13:14:52.020 回答