我正在使用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有区别吗?
更新
目前,对象模型尽可能简单,由一个 Word 对象组成,具有三个属性
NSString *字
NSString * sortedWord
NSInteger长度。
这是一个来自Instruments - Time Profiler的屏幕抓取(我不确定一种更好的方式来共享来自Instruments的数据),它显示(我认为)大部分时间花在[_NSPredicateUtiltiesDoRegexForString:Pattern:likeProtect :国旗:上下文:]
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:annotation:sql connection fetch time:10.7353s
CoreData:注释:总获取执行时间:24891行为10.7439s。
这里使用“raw”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中,因为它变得更大,如果可能的话)或者使用CONTAINS而不是LIKE(尽管这需要更改应用程序)逻辑),但是理解正在发生的事情会很好