【问题标题】:Iphone Sqlite3 Query too slowIphone Sqlite3 查询太慢
【发布时间】:2011-03-13 15:42:00
【问题描述】:

您好,我真的被我的应用程序卡住了。我需要使用 SQLITE3 在我的一张大约 250.000 行 (50mb) 的表上进行简单的 SELECT。当我使用 Iphone Simulator 加载时,查询大约需要 3 秒。当我在设备上测试我的应用程序时,查询需要 90 秒。不幸的是,我无法在等待 90 秒的情况下发布我的应用程序。在这里我发布我的代码:

-(void) loadResults {

sqlite3 *database;
NSMutableString *street;
zone = [[NSMutableArray alloc] init];

if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
    const char *sqlStatement = [[NSString stringWithFormat:@"select street from streets "] UTF8String];
    sqlite3_stmt *compiledStatement;
    if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
        while(sqlite3_step(compiledStatement) == SQLITE_ROW) {

            street = [NSMutableString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
            [zone addObject:street];
        }
    }   
    sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);}   

这就是我使用 SQLITE3 创建表的方式

CREATE TABLE streets (id INTEGER PRIMARY KEY, street TEXT, province TEXT, country TEXT, from TEXT, to TEXT, lat TEXT, lon TEXT);
CREATE INDEX strIndx on streets(street);

如您所见,没有 WHERE 语句,它只是一个简单的“SELECT street FROM street”

我需要帮助 提前致谢。

【问题讨论】:

    标签: iphone objective-c sqlite simulator


    【解决方案1】:

    如果您有 250,000 行只有 3000 个不同的结果,则每条街道平均在数据库中出现 83 次。

    也许将您的街道分成一个单独的规范化表是合适的,每个值只出现一次,然后通过 ID 从您的地址表中引用这些街道。然后对于您的 TableView,您可以只从 Streets 表中提取值。

    如前所述,您可能还会遇到 UI 范式问题。如果您在 UI 中有一个包含 3000 个条目的表,那么这对用户来说可能非常乏味。 (想象一下尝试一次向下滚动一部电影到 Yabar Street。)

    您可能希望至少像之前建议的那样延迟加载表。或者,也许您可​​以允许用户输入街道名称,并提供谷歌建议类型的界面,在他们输入时弹出潜在的匹配项。

    【讨论】:

    • 对不起,我没有看到这个回复,我会试试标准化的东西。谢谢杰森
    【解决方案2】:

    你想做什么?当你承认你没有 WHERE 语句时,我假设你没有做任何事情,比如过滤 Obj-C 端的行。因此,我唯一能想到的您正在尝试做的事情(如果我错了,请发表评论)是加载所有行以进行显示。苹果对此有一个非常简单的标准建议——延迟加载表格。基本上,在原始查询中添加一个限制,例如 15 行,并有办法检索更多行(通常这将是一个带有蓝色文本的表格页脚,上面写着“加载更多...”)。或者,这可以通过在请求之前不加载低于限制的单元格来实现(这将在用户滚动到它们时发生)。

    【讨论】:

      【解决方案3】:

      感谢您的回答 Jared,我需要在 UITableView 中显示所有街道,并让用户在 UISearchBar 中过滤搜索,或者让他从列表中选择它。我已将查询更改为

      SELECT DISTINCT(street) from streets
      

      这返回了 3000 行的结果,但它所花费的时间与没有 DISTINCT 的时间相同,即 90 秒。我也尝试过“GROUP BY street”,没有任何好处。但是,如果我添加 .. LIMIT 3000 结果是即时的。我想查询必须遍历整个表才能获得 DISTINCT 值,这与 LIMIT 无关,这可能是 INDEX 的问题吗?我如何知道索引是否有效? 再次感谢!

      【讨论】:

      • 关于 SQL 优化,我不知道,但这基本上是一个单独的问题
      猜你喜欢
      • 2015-05-12
      • 2014-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-14
      • 2020-10-14
      相关资源
      最近更新 更多