setFetchBatchSize似乎无法正常工作

时间:2012-04-25 15:51:48

标签: objective-c ios core-data nsfetchrequest

我就这个主题提出几个问题,但仍然无法使其发挥作用。我有一个核心数据,有10k +行的人名,我在tableview中显示。我希望能够用每个字母搜索和更新表格。这是非常迟钝的。正如我所建议的那样,我观看了WWWDC '10核心数据演示,并试图实施

[request setFetchBatchSize:50];

似乎不起作用。当我使用工具检查核心数据时,它仍然显示在加载tableview时仍有10k请求,当我搜索它时也获得所有结果。 是否还需要做任何其他事情来设置批量大小,或者那些不会对我有帮助。

唯一可行的方法是在搜索时将fetchlimit设置为100。你认为这是一个很好的解决方案吗?

提前致谢!

1 个答案:

答案 0 :(得分:12)

批量大小只是告诉它一次要获取多少个对象。这可能不会对你有所帮助。让我们稍微考虑一下你的用例......

用户键入“F”并告诉数据库“Go找到所有以'F'开头的名称”,数据库查看所有10k +记录,找到以'F'开头的记录

然后,用户键入'r',因此您告诉数据库找到所有以“Fr”开头的记录,然后再次查看所有10k +记录,找到以“Fr”开头的记录。

所有fetchBatchSize正在告诉它“嘿,当你在记录中出错时,立刻引进50,因为我可能还需要所有这些。”这无助于限制您的搜索。

但是,将fetchLimit设置为100有助于一些因为数据库开始搜索所有10k +记录,但是一旦它有100条记录,它就不必继续查看其余的记录,因为它已经填满了它的请求。它已经完成,并且一旦获得满足请求的100条记录就停止搜索。

因此,您可以执行以下几项操作,具体取决于您的其他用例。

最简单的尝试是在您要搜索的字段上添加索引。您可以在Xcode模型编辑器中设置它(指向Indexes的部分,在您可以在检查器中命名实体的位置)。这将允许数据库在该字段上设置特殊索引,搜索速度会快得多。

其次,在您的初始请求之后,您已经有一个以'F'开头的名称数组,因此无需返回数据库来询问以'Fr'开头的名称如果它以'Fr'开头'它也以'F'开头,你已经有了所有这些的NSManagedObject指针。现在,你可以搜索你得到的数组。

更好的是,如果你给它一个排序描述符,那么数组就会被排序。因此,您可以在阵列上进行简单的二进制搜索。或者,如果您愿意,可以使用相同的谓词,并将其应用于结果数组而不是数据库。

即使您不使用我刚刚讨论过的结果修剪,我认为对该属性进行索引也会显着。

修改

也许你应该运行乐器,看看你花多少时间在哪里。而且,一个形式错误的谓词可以使任何指数方案屈服。代码会有所帮助。

最后,考虑一下你带入内存的元素数量。 CoreData不会对所有信息进行错误处理,但它会为数组中的所有内容创建shell。

如果你给它一个排序谓词,

我不知道SQLLite如何在索引上实现其搜索,但是B-Tree具有复杂性logBN,所以即使在30k记录上,这也不是很多搜索。除非你有其他问题,否则索引应该给你一个很大的改进。

获得索引后,您不应该检查所有记录。但是,您仍可能拥有非常大的数据集。在那些上尝试fetchBatchSize,因为它将限制获取的记录数,并为其余的创建代理。

您也可以调用countFetchRequext而不是executeFetchRequest来获取项目数。然后,您可以使用fetchLimit来限制您获得的数字。

至于使用获取的结果控制器完成所有这些......好吧,那个人必须知道记录,所以它仍然必须进行搜索。

另外,还有一个地方可以看......你在做什么?如果你有任何用户定义的比较器(比如翻译部分),那么每个记录都会调用它。

因此,我想我的重要建议是,在改变指数后,运行工具并真正研究它以确定你在哪里花时间。应该很明显。这将有助于引导您走向真正的问题。

我敢打赌,由于某种原因,你仍然可以访问所有元素......