2011-05-04 123 views
2

我使用iOS 4.3.2在iPad上運行以下核心數據讀取請求。在iPad上核心數據讀取速度非常慢

NSPredicate *predicate = [NSPredicate predicateWithFormat: 
          @"feed.account.name == %@ AND feed.feedType == %@", accountName,feedType]; 

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" 
                   ascending:NO]; 

NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 

fetchedResultsController=[self createFetchedResultsController:@"RssFeedItem" predicate:predicate sortDescriptors:sortDescriptors]; 

[fetchedResultsController.fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:@"url",@"headline",@"isRead",@"origin",@"originId",@"date",nil]]; 


[fetchedResultsController.fetchRequest setFetchLimit:500]; 

[fetchedResultsController setDelegate:self]; 

[fetchedResultsController performFetch:&error]; 

return [fetchedResultsController fetchedObjects]; 

我有大約688排在RssFeedItem表SQLite數據庫的數據,並在所有其他表小於100行。該查詢使用調試日誌記錄爲:

CoreData: sql: SELECT t0.Z_ENT, t0.Z_PK, t0.ZURL, t0.ZHEADLINE, t0.ZISREAD, t0.ZORIGIN,   
CoreData: annotation: sql connection fetch time: 3.3854s 
CoreData: annotation: total fetch execution time: 3.4178s for 688 rows. 

而且運行速度很慢(超過3秒)。我有所有必需的搜索字段和排序字段的索引。我假設也許2路連接使它變慢,但不知道爲什麼會這麼慢。有沒有什麼辦法來優化這段代碼或查詢,還是有什麼我應該看看?

回答

1

這似乎有點慢。我不知道這是否會產生巨大的速度差,但它應該幫助一點點,因爲返工您的斷言:第一

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"feed.feedType == %@ AND feed.account.name == %@", feedType, accountName]; 

你想要把最便宜的條件,這樣更昂貴的情況不會必須在所有情況下進行檢查。檢查帳戶名時發生的連接要貴得多。此外,根據Feed類型的值是什麼樣子,它可能會更快地將其切換爲整數(我假設它是一個字符串,因爲它是一個對象)。

+0

非常感謝,所以我會先試一試。 – 2011-05-06 14:19:34

+0

我試着重新安排上面指定的謂詞。但仍然很慢: 'CoreData:sql:SELECT t0.Z_ENT,t0.Z_PK,t0.ZURL,t0.ZHEADLINE,t0.ZISREAD,t0.ZORIGIN,t0.ZORIGINID,t0.ZDATE FROM ZFEEDITEM t0 JOIN ZFEED t1 ON t0.ZFEED = t1.Z_PK JOIN ZFEEDACCOUNT t2 ON t1.ZACCOUNT = t2.Z_PK WHERE((t1.ZFEEDTYPE =?AND t2.ZNAME =?)AND t0.Z_ENT =?)ORDER BY t0.ZDATE DESC LIMIT 500' CoreData:annotation:sql connection fetch time:4.0500s' 'CoreData:annotation:total fetch execution time:4.0797s for 500 rows.' – 2011-05-06 14:36:13

+0

您的謂詞仍然會很慢,因爲其中有2個連接發生。您可能需要重構您的模型以獲得重大改進。發佈您的模型,我們可能會提出一些改進建議。基本上,你希望儘可能地在你要獲取的實體中擁有你在謂詞中檢查的值,而不是在關係中。 – McCygnus 2011-05-07 05:46:10

2

我想,它們會減慢您的查詢線下是

[fetchedResultsController.fetchRequest setPropertiesToFetch:[NSArray 
arrayWithObjects:@"url",@"headline",@"isRead",@"origin",@"originId",@"date",nil]]; 

[fetchedResultsController.fetchRequest setFetchLimit:500]; 

我很好奇,爲什麼你需要獲取所有這些屬性(500項)一旦?

+1

另外,我同意@McCygnus,重新排序你的謂詞可能會有所作爲。 – uvesten 2011-05-04 22:20:28

+0

我不認爲這是問題,因爲我有更大的數據庫和取500行的其他應用程序是相當快的。這個數據庫很小(少於1000行),所以我不知道它可能需要3秒鐘。我可以在幾毫秒內在內存中創建500個全新的對象。我也可以非常快速地枚舉數據庫中的所有對象(不使用查詢/謂詞等) - 似乎生成的查詢只是通過核心數據或SQLlite處理得非常差。 – 2011-05-06 14:19:03

+0

但是,這個查詢不僅僅是枚舉或者讀取索引,它實際上是從磁盤讀取數據。 (這可能是一個糟糕的實現,我自己並不喜歡CoreData。)但是,這個查詢需要從磁盤讀取500 * 6 = 3000個字符串,創建3000個nsstrings,然後用數據填充它們。我認爲這不是微不足道的。 – uvesten 2011-05-06 14:47:02