我有一个 CoreData 模型,其中包含大量可搜索的“食谱”对象。为了搜索效率,我有一个名为“关键字”的引用模型,它只有一个“术语”属性(索引)。该术语是一个单词,从“食谱”的名称进行处理和规范化。
因此,例如,如果一个食谱名为 Crème Brûlée,它将有两个关键字“creme”和“brulee”,然后我还将用户的搜索标准化,以便他们可以使用重音词来查找非重音词,反之亦然。
当用户搜索时,我将字符串归一化,然后用空格分割。搜索配方结果必须包含以所有拆分搜索组件开头的关键字。
我创建了一个动态谓词,该谓词根据用户正在搜索的单词数而增长。
如果您正在搜索“crem”,则谓词将变为:
[NSPredicate predicateWithFormat:@"ANY keywords.term BEGINSWITH %@", @"crem"]
如果您搜索“crem bru”:
[NSPredicate predicateWithFormat:@"ANY keywords.term BEGINSWITH %@ AND ANY keywords.term BEGINSWITH %@", @"crem", @"bru"]
现在,我面临的问题。
就一个字,这速度很快。我可以在 3GS 上运行它,实时搜索建议没有明显滞后。当您在搜索中添加后续单词时,问题就出现了。我查看了 SQL 输出,我认为问题在于 CoreData 正在为每个“ANY keywords.term BEGINSWITH”做一个 INNER JOIN,但如果我自己重写查询,我可以简单地用一个 INNER JOIN 来完成。
在 3GS 上运行:
单个字(0.0262 秒):
CoreData: sql: SELECT DISTINCT t0.Z_ENT, t0.Z_PK, t0.ZID, t0.ZNAME FROM ZCDRECIPE t0 JOIN Z_4RECIPES t1 ON t0.Z_PK = t1.Z_5RECIPES JOIN ZCDKEYWORD t2 ON t1.Z_4KEYWORDS = t2.Z_PK WHERE NSCoreDataStringSearch( t2 .ZTERM, ?, 8, 0) 按 t0.ZNAME 排序
CoreData:注解:sql连接获取时间:0.0262s
多字(0.2996 秒):
CoreData: sql: SELECT DISTINCT t0.Z_ENT, t0.Z_PK, t0.ZID, t0.ZNAME FROM ZCDRECIPE t0 JOIN Z_4RECIPES t1 ON t0.Z_PK = t1.Z_5RECIPES JOIN ZCDKEYWORD t2 ON t1.Z_4KEYWORDS = t2.Z_PK JOIN Z_4RECIPES t3 ON t0.Z_PK = t3.Z_5RECIPES JOIN ZCDKEYWORD t4 ON t3.Z_4KEYWORDS = t4.Z_PK WHERE (NSCoreDataStringSearch(t2.ZTERM, ?, 8, 0) AND NSCoreDataStringSearch(t4.ZTERM, ?, 8, 0)) 按 t0 排序。名称
CoreData:注解:sql连接获取时间:0.2996s
即使它正在查看同一个表,您也可以看到,CoreData 不止一次地与 ZCDKEYWORD 进行了 INNER JOINing。
在我的谓词中,有没有办法让它只将关键字表加载到连接中?
谢谢