我正在访问近30,000个单词并显示在表格中。这些单词在sqlite文件中。因此,运行查询并在表中加载单词需要很长时间(15秒)。显然,应用程序在启动时等待15秒。
我该如何解决这个问题?
NSLog(@"Query start");
CFTimeInterval startTime = CFAbsoluteTimeGetCurrent();
FMResultSet *rs = [db executeQuery:@"select * from words order by no ASC "];
while ([rs next]) {
Word *word = [[Word alloc] initWithID:[rs intForColumn:@"id"]
no:[rs stringForColumn:@"no"]
en:[rs stringForColumn:@"en"]];
[words addObject: word];
}
[rs close];
[db close];
CFTimeInterval endTime = CFAbsoluteTimeGetCurrent();
float deltaTimeInSeconds = endTime - startTime;
NSLog(@"Time spent for query: %f seconds", deltaTimeInSeconds);
注意:原始表未排序。它是字典的单词列表,因此何时显示,它必须在表格视图中按字母顺序排序。这就是为什么,我需要加载所有的单词。后台线程可能是一个更好的主意,从sqlite获取时填充数据。 sqlite支持这个吗?使用回调方法获取数据。例如在sqlite查询中,对于每次获取的1000条记录,我将更新我的表。我不太清楚怎么做,如果你知道plz给我一些提示。
答案 0 :(得分:3)
使用LIMIT
和OFFSET
一次获取数据块。另外,让UITableView驱动提取过程。当它触发tableView:cellForRowAtIndexPath:
并且有问题的行不可用时,从SQLite中获取并缓存包含该行的行块。您还可以使用后台线程或事件循环在后台获取块,以便在用户滚动表时最大限度地减少延迟。
答案 1 :(得分:1)
我建议两件事:
首先:您是否需要同时在内存中加载所有30000个对象?如果您不需要它,只要您需要它们,您就可以加载要在表格中显示的对象。您可以在查询中使用limit
子句来加载显示所需的一小部分数据。
第二:您可以尝试查看在no
字段上创建索引是否有帮助。虽然在很大一部分时间内不太可能提高性能,但iOS会花费创建Word
个对象并将它们放在words
数组中。
答案 2 :(得分:1)
您可能还想考虑切换到Core Data和NSFetchedResultsController而不是直接使用Sqlite。
Core Data的一大好处是它在缓存和延迟加载对象方面为您提供的。