CoreData 和大表

Posted

技术标签:

【中文标题】CoreData 和大表【英文标题】:CoreData and big tables 【发布时间】:2011-05-02 12:35:51 【问题描述】:

我有一个 Cocoa Mac 应用程序,其中包含一个搜索字段和一个通过 CoreData 绑定到 sqlite 表的集合视图。该表包含数十万条记录,其中包含按名称索引的文本字段(名称、地点、...)。我在搜索字段绑定中使用 BEGINSWITH 谓词来选择要在集合视图中显示的十几条记录。一切正常,但问题是 CoreData 在第一次查询请求时将整个表加载到内存中,然后才对显示的记录进行必要的过滤,这对用户来说意味着相当大的延迟。

有没有办法设置 CoreData 使整个表不加载到内存中?理想情况下,对于搜索字段中的每个查询,我只想从一系列按字母排序的记录中获取前 100 个项目。

【问题讨论】:

一些建议。您没有“通过 CoreData 绑定到 sqlite 表的集合视图”。核心数据不是 SQL。实体不是表格。对象不是行。属性不是列。关系不是连接。 Core Data 是一个对象图管理系统,它可能会也可能不会持久化对象图,并且可能会或可能不会在幕后使用 SQL 来做到这一点。试图用 SQL 术语来思考 Core Data 会导致您完全误解 Core Data 并导致很多痛苦和浪费时间。 是什么让您认为“CoreData 在第一次查询时将整个表加载到内存中......”?核心数据不是那样工作的。你只是假设因为应用程序很慢吗? @TechZen:我明白你的意思。我的问题是我的微不足道的应用程序在启动时很慢。我试图通过将一些调试日志记录到 NSArrayController fetchWithRequest 方法覆盖中来弄清楚发生了什么,我发现整个表确实在第一个请求时被加载到数组控制器中,尽管我只想显示前 100 条记录我的收藏视图。我是 Cocoa 的新手,我很确定这只是设置不当的问题。我很感激任何可以为我指明正确方向的提示。 【参考方案1】:

ios 上,这将使用 NSFetchedResultsController 来实现。以下问题描述了 Mac 等效控制器(例如 NSArrayController):NSFetchedResultsController Mac OSX Cocoa equivalent。

编辑

根据我在下面的评论,NSFetchRequest 应该与阵列控制器一起创建。然后可以使用fetchLimitfetchOffset 对其进行配置,以确定返回多少获取结果。

【讨论】:

是的,我一直在使用 NSArrayController。问题是它被填充了一个查询:从 mytable 中选择名称;这是超过 10 万条记录。我想让它填充类似的内容:从 mytable 中选择名称,其中名称如 'j%' order by name limit 100;这样数组控制器只携带那些实际显示在我的集合视图中的条目。 @mschuster:要限制返回的结果数量,请将您的NSArrayController 配置为使用NSFetchRequest。您可以继承 NSArrayController 并覆盖 fetchWithRequest:merge:error: 方法。您的NSFetchRequest 可以配置fetchLimitfetchOffset 以确定提取应该返回多少结果。 +1 数组控制器应该只在实际需要的托管对象中获取和故障,以便立即显示 tableview。设置 fetchLimit 等会更有帮助,尽管根据我的经验,数组控制器很少需要它。【参考方案2】:

确保您将提取请求设置为仅作为故障提取。这样,只有那些属性被主动访问的对象才会被完全加载到内存中。

【讨论】:

以上是关于CoreData 和大表的主要内容,如果未能解决你的问题,请参考以下文章

hive join 优化 --小表join大表

CoreData(iOS):是不是需要创建数据库才能使用CoreData?coredata可以对简单的平面文件进行操作吗? [关闭]

CoreData 本地数据存储

CoreData与CloudKit同步时将图像保存到CoreData?

RestKit + CoreData:从CoreData缓存中排除某些对象

Coredata — 入门使用