Sqlite + 80K行+ LIKE =键盘滞后

时间:2009-05-04 10:48:58

标签: iphone sqlite keyboard performance sql-like

我遇到了这个问题,我一直在推迟解决,但现在是时候了。

我有一个基本的字典程序。它有一个UISearchBar和一个UITableView。它的工作方式除了在设备上运行时它会导致键盘滞后。 (模拟器很好,当然)我有两种类型的搜索。按你型和回程。我发现两者都需要大约相同的时间来返回结果,但是As-you-type会使键盘滞后。

我有UISearchBar textDidChange,它接受searchText并将其发送到执行所有sqlite提升的搜索方法,将结果放入数组中。重新加载表。

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
    if((searchType == SEARCH_AS_YOU_TYPE) && ([searchText length] >= 2)){
        NSString *myKeyword = [NSString stringWithFormat:@"%@", searchText];
        [self search:myKeyword];
        [myTableView reloadData];
    }
}

我将结果限制为50.我的SQL查询使用了LIKE和OR,还没有办法解决。

SELECT WORD_ID, DEFIN, PINYIN, SIMP, TRAD from WORDS where DEFIN LIKE "%to dog %" OR DEFIN LIKE "%dog" OR DEFIN LIKE "%dog%"  ORDER BY DEFIN LIMIT 50

我也尝试将[myTableView reloadData]移动到搜索方法中,希望键盘至少不会滞后。没有喜悦。遗憾的是,我知道sqlite基本上是检查每一行,当它使用like运算符时。但是对于80人而言,3-4秒似乎有点慢。

任何想法,想法,意见或建议都将不胜感激!

5 个答案:

答案 0 :(得分:8)

听起来你正在搜索并准备好同一个线程中的键盘。这样,您将搜索与字符一样多的次数,并且打字速度仅限于搜索速度。

一个正确的解决方案是将其分为两个线程,一个用于读取和显示键盘,第二个用于搜索和显示搜索结果。这样,如果您输入的速度比搜索速度快,那么只有搜索会滞后,而不是输入。例如,Firefox地址栏以这种方式工作。

由于两个线程以及两者之间的通信/协调,您的代码将更加复杂,但我认为这是唯一的好解决方案。

答案 1 :(得分:3)

以下是我猜测SQLite执行该查询的方式:

  1. 查找与您的LIKE语句匹配的所有行。

  2. 按DEFIN排序。

  3. 在前50行之后截断结果。

  4. 我怀疑真正痛苦的部分是那种;没有它,它可以简单地收集它找到的前50个匹配行。你能不解决这些定义吗?

答案 2 :(得分:1)

因为您正在使用LIKE sqlite将不会使用索引,它将从开始顺序扫描,直到达到结果集中的50条记录的限制。根据您的数据顺序,它可能会在开始或结束时遇到前50个结果。

如何创建新列,用于存储defin中每个基本单词的第一个字母,即d代表dog等,并为此列编制索引。

修改您的查询以从fisrtletter =的词语中选择*:通过定义限制50的第一顺序

这会显着缩短您的搜索空间

使用like运算符进行完全匹配

您也可以预先订购数据,以便不需要订单,我怀疑订单会导致扫描整个表而不是在前50个记录被点击时终止

答案 3 :(得分:0)

尝试在其他线程中进行搜索查询。由于UI操作仅在主线程上执行,因此在主线程上执行的任何耗时操作都将延迟UI操作。

答案 4 :(得分:0)

我通常使用

[self performSelectorInBackground:@selector(threadedFetch) withObject:nil];

与Core Data的NSFetchedResultsController结合使用,以便在用户搜索输入时开始提取。但是在踩踏时要小心。为每个帖子使用单独的NSManagedObjectContext,或者使用-[NSManagedObjectContext lock]锁定的单个上下文。