在iphone上的tableview上的sqlite db上文本搜索速度太慢

时间:2010-08-05 18:53:28

标签: iphone search sqlite performance tableview

我有一个大约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,因此它会不断追加搜索字符。当用户输入键盘键时,键盘变得非常粘,输入速度很慢。任何建议将不胜感激......

2 个答案:

答案 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);

所以在你的情况下:

  1. 将您的数据库存入Mac。
  2. 使用shell来诊断哪些查询速度很慢。
  3. 研究查询以了解它们为何缓慢:需要编入索引的内容?并且不太可能:查询有什么尴尬,阻止查询优化器选择合理的计划?
  4. 添加适当的索引或调整查询。
  5. 重新测试以确保更改有效。
  6. 使用SQLite的经验法则很简单:如果你要搜索它,它应该被编入索引。

答案 1 :(得分:1)

在第一个字符之后,将结果数据复制到一个数组中,然后使用谓词过滤数组。它快得多。然后从数组中重新加载表。该数组可能是一个字典数组,其中每个元素都是带有搜索字符串的字典(即名称或其他),另一个条目是您希望作为最终选择的核心数据实体的引用。或者,您可以在用户进行选择时最终选择核心数据。

请注意,使用谓词进行过滤时,数组中的对象需要具有与您要搜索的属性匹配的属性。在我的示例中,我创建了一个具有属性fullName emailAddressString等的对象。

predicate = [NSPredicate predicateWithFormat:@“fullName包含[cd]%@或emailAddressString包含[cd]%@”,searchString,searchString];

NSArray * resultArray = [[NSArray alloc] initWithArray:[allContacts filteredArrayUsingPredicate:predicate]];