ここからダウンロードできる非常に小さなサンプルプロジェクトを使用しています。私がやろうとしているのは、自分のプロジェクトでフェッチに時間がかかる理由をデバッグすることですが、このプロジェクトを一種のベンチマークとして使用しました。スキームで有効-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
これは奇妙な振る舞いですよね?誰かがこれをすばやく複製して、何が起こっているのか、そしてなぜ私が何千行もの出力を取得しているのかを説明できますか?