1

所以这是我的问题,我是 iOS 的 CoreData 的新手,所以我不太确定如何优化,但我在这里看到了很多其他问题,我已经尽我所能进行优化,但由于某种原因,获取 100 行仍然需要将近 5 秒!这是它被调用的代码:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    [self titles:searchText];
}
-(NSArray *)titles:(NSString *)toMatch
{
    NSMutableArray * retval = [[NSMutableArray alloc] init];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if(toMatch.length>2)
    {
        NSString *LabelText =toMatch;
        NSString *compareString = @"";
        for (int i = 0; i<LabelText.length; i++)
        {
            int letter = [LabelText characterAtIndex:i];
            NSString *blah;
            if(letter<100)
            {
                blah = [NSString stringWithFormat:@"0"];
                blah = [blah stringByAppendingFormat:@"%d", letter];
            }
            else
                blah = [NSString stringWithFormat:@"%d", letter];
            compareString= [compareString stringByAppendingString:blah];
            compareString = [compareString stringByAppendingString:@","];
        }
        NSFetchRequest *request = [[NSFetchRequest alloc] init];
        [request setEntity:entity];
        NSPredicate *predicate;
        if ([defaults boolForKey:@"FLS"])
            predicate = [NSPredicate predicateWithFormat:@"first_letter_start BEGINSWITH %@", compareString];
        else
            predicate = [NSPredicate predicateWithFormat:@"first_letter_start CONTAINS %@", compareString];
        [request setPredicate:predicate];
        [request setFetchLimit:100];
        [request setFetchBatchSize:1];
        [request setPropertiesToFetch:[NSArray arrayWithObject:@"gurmukhi"]];
        [request setReturnsObjectsAsFaults:NO];
        NSError *error;
        NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:request error:&error];
        for (Gurbani *shabad in fetchedObjects)
        {
            [retval addObject:shabad.gurmukhi];
        }
        searchResults = retval;
        [searchResultsTable reloadData];
    }
    return retval;
};

这是放入调试参数后的日志:

2013-01-11 18:04:57.195 GurbaniKhoj[2833:907] CoreData: sql: pragma cache_size=200
2013-01-11 18:04:57.199 GurbaniKhoj[2833:907] CoreData: sql: SELECT Z_VERSION, Z_UUID, Z_PLIST FROM Z_METADATA
2013-01-11 18:05:01.139 GurbaniKhoj[2833:907] CoreData: sql: SELECT 0, t0.Z_PK FROM ZSHABAD t0 WHERE  NSCoreDataStringSearch( t0.ZFIRST_LETTER_START, ?, 8, 0)  LIMIT 100
2013-01-11 18:05:06.705 GurbaniKhoj[2833:907] CoreData: annotation: sql connection fetch time: 5.5652s
2013-01-11 18:05:06.707 GurbaniKhoj[2833:907] CoreData: annotation: total fetch execution time: 5.5682s for 92 rows.

这是怎么回事?我能做些什么来让它更快?

编辑:我注意到的另一件事是这个速度并不一致。对于某些查询,它是 5.5 秒,对于其他查询是 1.8 秒。我不知道是什么导致了波动。

编辑 2:发现我的索引没有被创建。创建了一个版本化的数据模型,确保它们被索引,现在这就是日志的样子

2013-01-15 03:06:29.671 GurbaniKhoj[1212:907] CoreData: sql: SELECT 0, t0.Z_PK FROM ZSHABAD t0 WHERE  NSCoreDataStringSearch( t0.ZFIRST_LETTER_START, ?, 8, 0)  LIMIT 100
2013-01-15 03:06:31.130 GurbaniKhoj[1212:907] CoreData: annotation: sql connection fetch time: 1.4588s
2013-01-15 03:06:31.132 GurbaniKhoj[1212:907] CoreData: annotation: total fetch execution time: 1.4607s for 92 rows.

编辑3:有什么办法可以让这更快吗?尽管我正在对每个字符串进行这些字符串比较,但我仍然觉得 1.5 秒不是很快。

4

2 回答 2

2

穆基,

首先,您是否已经完成了显而易见的事情并为您的领域编制了索引?

其次,iOS 设备的获取时间非常慢。这在技术上并不是 Core Data 的缺陷。(尽管 CD 在这里也可能是性能下降的罪魁祸首。)因此,只要有可能,您应该在 RAM 中进行大量提取并在那里细化您的搜索。例如,当第一个字符是“b”时,获取所有这些字符,然后使用后续键入的字符从 RAM 中的该子集中进行细化。你会发现这是相当快的。

第三,您看到的性能变化可能是由于 SQLite 行缓存以及可能是填充的 MOC。

安德鲁

于 2013-01-12T14:46:54.907 回答
0

尝试将 fetch batch size 从 1 更改为 20。

[request setFetchBatchSize:20];
于 2013-01-15T08:26:28.387 回答