Iphone Sqlite3查询太慢

发布于 2024-09-08 21:54:22 字数 1238 浏览 2 评论 0原文

你好,我真的被我的应用程序困住了。我需要使用 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”,

请我在这里需要帮助 提前致谢。

Hello I'm really stuck with my app. I need to make a simple SELECT on one of my tables with aprox 250.000 rows (50mb) using SQLITE3. When I load with Iphone Simulator the query takes 3 sec aprox. When i test my app on the Device the query takes 90 sec. Unfortunately I can't release my app with 90 sec of wait. Here i post my code:

-(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);}   

This is how i've created my table using 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);

As you can see there is no WHERE statement, it is only a simple "SELECT street FROM streets"

Please I need help here
Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

も让我眼熟你 2024-09-15 21:54:22

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

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

正如之前提到的,您可能还会遇到 UI 范例问题。如果 UI 中有一个包含 3000 个条目的表,这对于用户来说可能会非常乏味。 (想象一下尝试一次向下滚动到 Yabar Street。)

您可能至少需要延迟加载表格,正如之前所建议的那样。或者,也许您可​​以允许用户输入街道名称,并提供 Google 建议类型的界面,在用户输入时弹出潜在的匹配项。

If you have 250,000 rows with only 3000 distinct results, each street is in the database 83 times on average.

Perhaps it would be appropriate to separate your streets into a separate, normalized table, with each value occurring only once, then reference those streets from your address table by ID. Then for your TableView, you could pull back just the values from your Streets table.

As was mentioned before, you may also have a UI paradigm issue. If you have a table with 3000 entries in it in the UI, that could potentially be very tedious for the user. (Imagine trying to scroll down one flick at a time to Yabar Street.)

You may want to at least lazy load the table, as was suggested before. Or maybe you can allow the user to type a street name, and provide a Google-suggest-type interface, popping up potential matches as they type.

所有深爱都是秘密 2024-09-15 21:54:22

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

What are you trying to do? As you acknowledge you have no WHERE statement, I'm assuming you aren't doing anything like filtering the rows on the Obj-C side. Therefore the only thing I can think of that you are trying to do (please comment if I'm wrong) is load all of the rows for display. Apple has a very simple standard recommendation for this -- lazily loading the table. Basically, add a limit of, say, 15 rows to the original query, and have a way to retrieve more (typically this would be a table footer with blue text saying 'Load more...'). Alternatively this could be implemented by simply not loading the cells below the limit until requested (which will happen when the user scrolls to them).

多像笑话 2024-09-15 21:54:22

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

SELECT DISTINCT(street) from streets

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

Thank you for your answer Jared, what I need is to show all the streets in a UITableView and let the user filter the search in a UISearchBar or just let him select it from the list. I've changed my query to

SELECT DISTINCT(street) from streets

This returned a 3000 rows result but it takes the same amount of time as without the DISTINCT, that is 90 sec. I've also tried with "GROUP BY street", no benefits. However if I add .. LIMIT 3000 the result is instant. I imagine the query has to move through the whole table to get the DISTINCT values, which doesn't do with LIMIT, can it possible be a matter of the INDEX? How do I know if the index is working?
Thanks again!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文