给出两个表:
Data - Contains raw data, per value per day. ----------- Value | Price | Date | DataType (string)
数据可能包含:
Units | Price | Date | DataType --------------------------------- 10 | 0.99 | March 1, 2014 | "1A" 20 | 0.99 | March 1, 2014 | "1B" 4 | 0.99 | March 1, 2014 | "2"
可能有数十万条记录。
通常要查询Data
我会使用谓词,例如(使用MagicalRecord):
NSArray * results = [Data MR_findAllWithPredicate: [NSPredicate predicateWithFormat: @"date > x AND date < y AND dataType IN ('1A', '1B')"]];
// Calculate sums per day.
// .... Loops through results, units * price summed per day.
但是由于行数很多,这种情况变得非常缓慢。
有一些事情我试图让这个更快。
通过NSExpression
求和。不幸的是,由于需要使用multiple:by
表达式,这不起作用。 (Fetch aggregate data from NSManagedObject using another expression as argument to sum: expression了解更多详情)。
现在我的想法是创建一个缓存表。我试图使用如下结构:
CachedData ----------- Sum | Date | CacheType (integer)
我创建并测试了插入数据并且它似乎更快(我的一些计算从~7秒到约0.5秒)。但问题是通过核心数据创建此缓存表。
如果我使用原始SQLite,我可以做类似的事情:
INSERT INTO CachedData (CacheType, Sum, Date) SELECT 0, (Value * Price), Date FROM Data WHERE DataType IN ('1A', '1B') AND NOT EXISTS(SELECT * FROM CachedData WHERE CacheType = 0 AND CachedData.Date = Data.Date);
然后,任何时候数据都有新的插入(永远不会更新,只是插入),我可以快速运行这个查询,让它只更新我的新数据。
另一方面,在coredata中,除了选择所有未缓存的数据,选择所有缓存的数据并做一些for循环之外,我似乎无法找到一个很好的方法来做到这一点。比较存在,然后插入。虽然这样可行,但它是SLOOOOOOOOW(相对于sqlite查询,可以在几秒钟内完成)。
在考虑这个问题时,我认为一种简单的方法是在我的数据表中添加cached
bool列。然后至少在我的枚举循环中,我可以对该列做一个谓词。我仍然有兴趣知道是否有办法通过coredata这样做而不添加额外的列。
TL; DR
有没有办法可以获取另一个表中不存在的一个表的所有记录?可能通过NSPredicate
子查询?
答案 0 :(得分:1)
首先,根据您的原始愿望,您是否将您的属性设置为索引?这有一些插入的开销,但会真正加快你想要的访问速度。
其次,为什么在插入数据时运行查询。您可以轻松地从MOC捕获DidSave
通知,并为新插入的对象执行您想要的操作,其中包括添加到另一个存储中。或者,您可以使用NSFetchedResultsController
并仅实现其委托...这将提供类似的结果,以便观察托管对象上下文中发生的事情......使用可能更熟悉的API。您不必使用带有TableView的FRC ......