3

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

[request setFetchBatchSize:50];

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

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

提前致谢!

4

1 回答 1

12

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

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

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

fetchBatchSize 所做的只是告诉它“嘿,当你在记录中出错时,立即带入 50 个,因为无论如何我可能需要所有这些。” 这不会限制您的搜索。

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

因此,您可以做几件事,这一切都取决于您的其他用例。

最简单的尝试是在您正在搜索的字段上添加索引。您可以在 Xcode 模型编辑器中设置它(索引部分,就在您可以在检查器中命名实体的位置下方)。这将允许数据库在该字段上设置一个特殊的索引,并且搜索会更快。

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

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

即使您不使用我刚刚讨论的结果修剪,我认为索引属性也会显着增加。

编辑

也许你应该运行仪器来看看你在哪里花费了多少时间。此外,格式错误的谓词可能会使任何索引方案陷入困境。代码会有所帮助。

最后,考虑一下您将多少元素带入内存。CoreData 不会对其中的所有信息进行故障排除,但它确实为数组中的所有内容创建了 shell。

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

我不知道 SQLLite 如何在索引上实现搜索,但是 B-Tree 具有复杂性 logBN,因此即使在 30k 条记录上,搜索也不是很多。除非您有其他问题,否则索引应该会给您带来很大的改进。

一旦你有了索引,你就不应该检查所有的记录。但是,您仍然可能拥有非常庞大的数据集。在这些上尝试 fetchBatchSize,因为它会限制获取的记录数,并为其余的创建代理。

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

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

另外,一个地方看...你在做部分吗?如果您有任何用户定义的比较器(例如翻译部分),则将为每条记录调用该比较器。

因此,我想我的主要建议是,在更改索引后,运行工具并真正研究它以确定您将时间花在哪里。这应该很明显。这将有助于引导您解决真正的问题。

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

于 2012-04-25T18:22:06.190 回答