批量大小只是告诉它一次要获取多少个对象。这可能不会对您有太大帮助。让我们考虑一下您的用例...
用户键入“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 来限制您获得的数量。
至于使用获取的结果控制器处理所有这些......好吧,那个人必须知道记录,所以它仍然必须进行搜索。
另外,一个地方看...你在做部分吗?如果您有任何用户定义的比较器(例如翻译部分),则将为每条记录调用该比较器。
因此,我想我的主要建议是,在更改索引后,运行工具并真正研究它以确定您将时间花在哪里。这应该很明显。这将有助于引导您解决真正的问题。
我敢打赌,由于某种原因,您仍然可以访问所有元素...