Swift CoreData:访问关系比仅通过谓词获取要慢 - 是这样设计的吗?
Posted
技术标签:
【中文标题】Swift CoreData:访问关系比仅通过谓词获取要慢 - 是这样设计的吗?【英文标题】:Swift CoreData: accessing relationship is slower than just fetching by predicate - is it designed that way? 【发布时间】:2022-01-06 06:43:50 【问题描述】:在我的应用中,我有 100 个图书馆,每个图书馆包含 5000 本书。
如果我想打印 10 个库和它们最近添加的 10 个,我可以通过访问关系来获取它们,然后 .suffix
返回的 NSSet
并运行 sort
或者我可以通过以下方式找到这些库留下一个libraryID
属性,我以后可以在NSPredicate
中使用,如下所示:
let fetchRequest = ... "Library"
let sort = NSSortDescriptor(key: "some key for ordering", ascending: false)
fetchRequest.sortDescriptors = [sort]
fetchRequest.fetchLimit = 10
let libraries = try context.fetch(fetchRequest) as? [Library]
for library in libraries
let fetchRequest = "Book"
fetchRequest.fetchLimit = 10
let predicate = NSPredicate(format: "libraryID == %@", library.id ?? "")
fetchRequest.predicate = predicate
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "added date", ascending: false)]
...
我不明白为什么第二个选项使用 15% 的 CPU,而直接访问关系却慢了大约 10 倍。
我对数据库的理解是,我们有适当的关系来防止做这类事情,在某种程度上将父属性的 ID 硬编码到子属性中,因为现在我质疑什么关系甚至有好处。
有一件事我可以看到一个有用的关系,即如果我们能够在Library
对象上执行.fetch
或者它是books
关系 - 这可能吗?因为这样我们就不必每次都扫描整个表,而只需在关系的条目中进行搜索。
【问题讨论】:
【参考方案1】:通过关系访问,然后排序和丢弃 4950 / 5000 个项目意味着所有这些处理都必须在内存中完成。使用获取请求意味着您可以让数据库完成工作。
如果图书馆与其书籍之间存在关系,则可以在谓词中使用它。在你上面的代码中,这将是这样的:
let predicate = NSPredicate(format: "library == %@", library)
这可能比存储 ID 更快,除非您在库 ID 上添加了索引。
【讨论】:
为我节省了 60% 的 CPU 时间。太感谢了。你能花点时间详细说明一下unless you have an index added on library ID
吗?这是什么意思?
您可以在核心数据模型编辑器中为字段添加索引,这将为数据库添加索引,可以加快访问速度,但会带来成本(写入速度较慢)以上是关于Swift CoreData:访问关系比仅通过谓词获取要慢 - 是这样设计的吗?的主要内容,如果未能解决你的问题,请参考以下文章
Swift coreData - 格式化日期并在谓词中使用它