核心数据获取请求在大型数据集上变慢

Kat*_*ins 4 core-data subquery large-files nsfetchrequest ios

这是我的第一个Core Data项目,我需要有关加快我的获取请求的建议.

我的核心数据模型包含2个实体,WellsFluids. Wells有50,000条记录,Fluids有200万条记录.它们看起来如下.

Wells
nams  
relation  
wellsToFluids

Fluids
text1, text2, etc.  
relation  
fluidsToWells  
Run Code Online (Sandbox Code Playgroud)

获取请求Wells非常快.获取请求WellsFluids通过复合谓词通过wellsToFluids关系访问的数据相结合是很慢的.而且,我在不同的谓词上看到意外的获取时间.

我正在根据用户选择构建复合谓词.但基本上情况如下

搜索Wells:

predicateWithFormat: @"(wellNumber == 1)"
Run Code Online (Sandbox Code Playgroud)

.001秒

流体搜索:

predicateWithFormat: @"(ANY  wellsToFluids.text2 CONTAINS[c] stringToFind)"
Run Code Online (Sandbox Code Playgroud)

1.3秒 (在Mac模拟器上 - 在iPhone或iPad上真的很慢)

抓取WellsFluids:

predicateWithFormat: @"(wellNumber == 1)  AND (ANY  wellsToFluids.text1 CONTAINS[c] stringToFind)"
Run Code Online (Sandbox Code Playgroud)

3.2秒

获取Wells和多个Fluids属性:

predicateWithFormat: @"(wellNumber == 1)  AND (ANY  wellsToFluids.text1 CONTAINS[c] stringToFind) AND (ANY  wellsToFluids.text2 CONTAINS[c] stringToFind)"
Run Code Online (Sandbox Code Playgroud)

6秒

Fluids谓词的部分更改为子查询会产生奇怪的结果.

Fluids使用子查询获取:

predicateWithFormat:@"(SUBQUERY(wellsToFluids, $x, ANY $x.text1 CONTAINS[c] stringToFind).@count !=0)"
Run Code Online (Sandbox Code Playgroud)

12秒

获取WellsFluids使用子查询:

predicateWithFormat: @"(wellNumber == 1)  AND  (SUBQUERY(wellsToFluids, $x, ANY $x.text1 CONTAINS[c] stringToFind).@count !=0)"
Run Code Online (Sandbox Code Playgroud)

3.2秒

对于在fetch中添加的其他属性,时间不会改变Fluids,保持相当恒定的3.2秒.

也尝试从中获取Fluids,然后使用关系返回Wells- 但这并没有提高速度.

有人可以给我一些关于改进获取设置的指示,或者它只是200万条记录的特征吗?

Lor*_*o B 6

这里有一些提示可以达到你想要的效果.无论如何,您总是需要测量您的更改,看它们是否有效.这是一个反馈过程.改变和衡量.改变和衡量等等.

  • 预先建立的关系
  • 使用批次
  • 喜欢beginwithendswith代替contains
  • 必要时避免[cd]
  • 规范化字符串
  • ...

这些只是提示.

我真的建议看看高性能核心数据博客.有关于如何实现这一目标的视频,幻灯片和代码.马修莫雷做得很好.

此外,在WWDC 2013视频中,Apple开发者网站(您必须是其成员才能观看)有一个名为核心数据性能优化和调试(会话211)的会话,其中讨论了性能.