【发布时间】:2014-12-20 23:23:12
【问题描述】:
我正在使用子查询谓词对核心数据托管对象上下文执行提取,以提取要放在地图上的实体。实体由相关实体上的属性过滤,因此使用子查询。子查询的谓词因用户选择的过滤条件而异。我发现这些子查询谓词中最简单的一个是导致提取所需的时间比预期的要长。
我的简化对象图如下所示:
Entity <-->> RelatedEntity <<--> FilterRelationship
-latitude
-longitude
NSFetchRequest 上的谓词如下所示:
(latitude > #.# AND latitude < #.# AND longitude > #.# AND longitude < #.#) AND SUBQUERY(relatedEntities, $relatedEntity, $relatedEntity.filterRelationship IN { JUST_ONE_HERE }).@count > 0
JUST_ONE_HERE 表示当子查询谓词的这部分集合中只有一个实体时,这是查询所需时间呈指数增长的地方。如果我在这个集合中有多个实体,查询将正常执行。
使用启动参数-com.apple.CoreData.SQLDebug 1,我记录了以下内容:
CoreData: sql: SELECT t0.Z_ENT, t0.Z_PK, t0.Z_OPT, ... FROM ZENTITY t0 WHERE (( t0.ZLATITUDE > ? AND t0.ZLATITUDE ? AND t0.ZLONGITUDE (?) )) > ?) ORDER BY . 限制 50
CoreData:注解:sql连接获取时间:903.6430s
CoreData:注释:总提取执行时间:903.6458s for 50 行。
和
CoreData: sql: SELECT t0.Z_ENT, t0.Z_PK, t0.Z_OPT, ... FROM ZENTITY t0 WHERE (( t0.ZLATITUDE > ? AND t0.ZLATITUDE ? AND t0.ZLONGITUDE (?,?) )) > ?) ORDER BY ...限制 50
CoreData:注解:sql连接获取时间:1.7181s
CoreData:注释:总提取执行时间:50 行 1.7216 秒。
我用... 删除了不重要的部分,并重命名了实体以明确它们是什么。但正如您所看到的,该查询正在获取类型为 Entity 的实体,基于它们在地图上的经度和纬度,以及基于相关实体 RelatedEntity 的子查询以及将这些相关实体上的关系与指定FilterRelationship 实体。
在子查询谓词的集合中只有一个 FilterRelationship 实体的简单情况下,提取大约需要 15 分钟。
上述两个查询之间的唯一区别是第二个查询在子查询谓词的集合中有两个FilterRelationship 实体。第二个示例在 2 秒内完成。
该数据库包含 ~22,000 个Entity、~5,000 个RelatedEntity 和 3 个FilterRelationship 实体。
我也尝试了同样的谓词,除了使用相等谓词代替 IN 一组一个对象。
(latitude > #.# AND latitude < #.# AND longitude > #.# AND longitude < #.#) AND SUBQUERY(relatedEntities, $relatedEntity, $relatedEntity.filterRelationship == JUST_ONE_HERE).@count > 0
这个谓词有同样的慢取结果。
搜索的Entitys 集越小,子查询谓词提取执行的速度就越快。因此,通过放大地图的一小块区域并让纬度/经度谓词过滤掉正在搜索的Entitys,尽管单个FilterRelationship 的速度很慢,但获取执行速度更快。大约 15 分钟的数字是在地图上一直放大时测量的,过滤数据库中的所有 Entitys。
编辑:
我更新了对象图以反映第一个关系 Entity 到 RelatedEntity 是一对多关系。第二个关系,RelatedEntity 到 FilterRelationship 是多对一关系。
【问题讨论】:
标签: ios objective-c sqlite core-data subquery