2014-03-28 18 views
0

鑑於兩個表項:CoreData - 獲取不另一個表中存在

 
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. 

但有大量行,這事變得非常緩慢。

有幾件事我試圖讓這個更快。

  1. 總和通過NSExpression。不幸的是,這不起作用,因爲需要使用multiple:by表達式。 (更多詳情,請致電Fetch aggregate data from NSManagedObject using another expression as argument to sum: expression)。

  2. 現在我的想法是創建一個緩存表。我試圖用一個結構如下所示:

 
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布爾列添加到我的數據表。然後至少在我的枚舉循環中,我可以對該列做一個謂詞。我仍然有興趣知道是否有辦法通過coredata做到這一點,但不添加額外的列。

TL; DR

有沒有方法可以讓我得到的是不要在另一個表中存在一個表中的所有記錄?子查詢可能通過NSPredicate

回答

1

首先,根據您的原始願望,您是否將您的屬性設置爲索引?這對於插入有一些開銷,但會真正加速訪問,就像你想要的。

其次,爲什麼在插入數據時運行查詢。您可以輕鬆地從MOC中獲取DidSave通知,併爲新插入的對象執行所需的操作,其中包括添加到另一個商店。或者,您可以使用NSFetchedResultsController並僅實現它的委託...,它將提供類似的結果,以便觀察託管對象上下文中發生的事情......以及可能更熟悉的API。您不必使用帶有TableView的FRC ...

相關問題