NSFetchedResultsController を使用して、約 250,00 の英単語の非常に単純なデータベースにクエリを実行しています。[NSCompoundPredicate andPredicateWithSubPredicates] を使用して次の述語を作成します。
"word LIKE '*a*' AND word LIKE '*b*' AND word LIKE '*c*' AND word LIKE '*d*'"
[NSFetchedResultController alloc] initWithFetchRequest:...] を呼び出してクエリを実行すると、実行に約 8 秒かかります。
sqlite3 を使用して、まったく同じデータベースで同等のクエリを実行できます。
"Select word from words where word LIKE '%a%' AND word LIKE '%b%' ..."
CPU 時間は約 0.01 秒です。
LIKE の使用、NSPredicate の使用、または NSFetchedResultsController の違いはありますか?
アップデート
現時点では、オブジェクト モデルは
NSString * word
NSString * sortedWord NSInteger length の 3 つのプロパティを持つ 1 つのWordオブジェクトで構成される、可能な限り単純なもの
です。
これは、Instruments - Time Profiler からのスクリーン グラブです (Instruments からデータを共有するためのより良い方法はわかりません)。これは、[ _NSPredicateUtiltiesDoRegexForString:Pattern:likeProtect:flags:環境:]。
http://www.mckaydalton.com/images/instruments.jpg
さらに、SQLDebug の出力は次のとおりです。
CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZLENGTH, t0.ZSORTEDSTRING, t0.ZWORD FROM ZWORD t0 WHERE ( NSCoreDataLike( t0.ZWORD, ?, 0) AND NSCoreDataLike( t0.ZWORD, ?, 0) ) ORDER BY t0.ZWORD
CoreData: 注釈: SQL 接続フェッチ時間: 10.7353 秒
CoreData: 注釈: 合計フェッチ実行時間: 24891 行で 10.7439 秒。
ここでは、同じデータベースで動作する「生の」sqlite3 を使用して同じ選択を行います。
SELECT 0, Z_PK, Z_OPT,ZSORTEDSTRING, ZWORD FROM ZWORD WHERE ZWORD LIKE '%a%' AND ZWORD LIKE '%b%' ORDER BY ZWORD;
CPU 時間: ユーザー 0.377206 sys 0.054738
したがって、NSCoreDataLike は、sqlite に組み込まれている「LIKE」とは非常に異なる動作をしているように思えます。これは大きな問題ではありません。C-api を使用して sqlite を実行するか (可能であれば、プロジェクトが大きくなるにつれて CoreData に保持したいのですが)、LIKE の代わりに CONTAINS を使用することができます (ただし、これにはアプリケーションを変更する必要があります)。ロジック)、何が起こっているのかを理解するのはいいことです