我有一个大约2500个条目的大表。我在tableview上显示它。但是在进行动态搜索时搜索栏太慢了。即每次用户在搜索栏上放置一个字符时,我都会过滤表格。
以下是代码:
- (void)searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {
if([searchText length] > 0) {
searching = YES;
letUserSelectRow = YES;
self.tableView.scrollEnabled = YES;
[self searchTableView];
} else {
searching = NO;
letUserSelectRow = NO;
self.tableView.scrollEnabled = NO;
[whereClause setString: @"%%"];
}
[self.tableView reloadData];
}
- (void) searchTableView {
NSString *searchText = searchBar.text;
[whereClause setString: @"%%"];
[whereClause appendString: searchText];
[whereClause appendString: @"%%"];
[self.tableView reloadData];
}
在sqlite查询中有whereClause,因此它会不断追加搜索字符。当用户输入键盘键时,键盘变得非常粘,输入速度很慢。任何建议将不胜感激......
答案 0 :(得分:3)
SQLite的选择通常非常快。如果您发布了一些示例查询,则可能更容易为您提供帮助。
但是,这说:如果您的查询具有执行缓慢的简单WHERE子句,则可能没有对要搜索的列的索引。添加一个。
对于SQLite,表中的2500个条目 NOT 大。 25,000,000会很大。
当您使用SQLite时,您可以使用sqlite3 shell在桌面上测试很多东西。例如,如果您的查询类似于:
SELECT * FROM MyTable WHERE Column='A';
您可以这样做:
EXPLAIN QUERY PLAN SELECT * FROM MyTable WHERE Column='A';
如果你看到这样的输出:
0|0|TABLE MyTable
这意味着SQLite正在抓取整个表格以获得结果。
在这种情况下,添加索引会有所帮助:
CREATE INDEX MyTableColumn ON MyTable(Column);
然后,上面的解释会给你这样的东西:
0|0|TABLE MyTable WITH INDEX MyTableColumn
如果您的WHERE子句更复杂,您可能需要编写复合索引,因为SQLite每个表只使用一个索引。
CREATE INDEX MyTableFirstSecond ON MyTable(First,Second);
所以在你的情况下:
使用SQLite的经验法则很简单:如果你要搜索它,它应该被编入索引。
答案 1 :(得分:1)
在第一个字符之后,将结果数据复制到一个数组中,然后使用谓词过滤数组。它快得多。然后从数组中重新加载表。该数组可能是一个字典数组,其中每个元素都是带有搜索字符串的字典(即名称或其他),另一个条目是您希望作为最终选择的核心数据实体的引用。或者,您可以在用户进行选择时最终选择核心数据。
请注意,使用谓词进行过滤时,数组中的对象需要具有与您要搜索的属性匹配的属性。在我的示例中,我创建了一个具有属性fullName emailAddressString等的对象。
predicate = [NSPredicate predicateWithFormat:@“fullName包含[cd]%@或emailAddressString包含[cd]%@”,searchString,searchString];
NSArray * resultArray = [[NSArray alloc] initWithArray:[allContacts filteredArrayUsingPredicate:predicate]];