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

时间:2013-12-09 02:14:51

标签: ios core-data subquery large-files nsfetchrequest

这是我的第一个核心数据项目,我需要有关加快获取请求的建议。

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

Wells
nams  
relation  
wellsToFluids

Fluids
text1, text2, etc.  
relation  
fluidsToWells  

Wells上的抓取请求非常快。 Wells上的抓取请求与来自Fluids的数据通过wellsToFluids关系通过复合谓词访问的请求很慢。并且,我在不同的谓词上看到意外的获取时间。

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

搜索Wells

predicateWithFormat: @"(wellNumber == 1)"

.001秒

对流体的搜索:

predicateWithFormat: @"(ANY  wellsToFluids.text2 CONTAINS[c] stringToFind)"

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

获取WellsFluids

predicateWithFormat: @"(wellNumber == 1)  AND (ANY  wellsToFluids.text1 CONTAINS[c] stringToFind)"

3.2秒

获取Wells和多个Fluids属性:

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

6秒

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

仅使用子查询获取Fluids

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

12秒

使用子查询获取WellsFluids

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

3.2秒

Fluids获取时添加的其他属性的时间不会改变,保持相当恒定的3.2秒。

还尝试从Fluids抓取,然后使用关系回Wells - 但这并没有提高速度。

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

1 个答案:

答案 0 :(得分:6)

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

  • 预取关系
  • 使用批次
  • 首选beginwithendswith代替contains
  • 必要时避免[cd]
  • 规范化字符串
  • ...

这些只是提示。

我真的建议你去看看High Performance Core Data博客。有关于如何实现这一目标的视频,幻灯片和代码。 Matthew Morey 表现非常出色。

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