2010-07-09 6 views
0

Bonjour, je suis vraiment bloqué avec mon application. Je dois faire un SELECT simple sur une de mes tables avec environ 250.000 lignes (50mb) en utilisant SQLITE3. Lorsque je charge avec Iphone Simulator, la requête prend environ 3 secondes. Lorsque je teste mon application sur le périphérique, la requête prend 90 secondes. Malheureusement, je ne peux pas libérer mon application avec 90 secondes d'attente. Ici, je posterai mon code:Iphone Sqlite3 Query trop lent

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

Voici comment je l'ai créé ma table à l'aide 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); 

Comme vous pouvez le voir il n'y a pas WHERE, il est un simple « SELECT rue de rues "

S'il vous plaît j'ai besoin d'aide ici Merci d'avance.

Répondre

2

Qu'est-ce que vous essayez de faire? Comme vous reconnaissez que vous n'avez pas de déclaration WHERE, je suppose que vous ne faites rien comme filtrer les lignes du côté Obj-C. Par conséquent, la seule chose que je peux penser que vous essayez de faire (s'il vous plaît commenter si je me trompe) est de charger toutes les lignes pour l'affichage. Apple a une recommandation standard très simple pour cela - chargement paresseux de la table. Fondamentalement, ajouter une limite de, disons, 15 lignes à la requête d'origine, et avoir un moyen d'en récupérer plus (généralement ce serait un pied de table avec un texte bleu disant «Charger plus ...»). Alternativement ceci pourrait être implémenté en ne chargeant simplement pas les cellules au-dessous de la limite jusqu'à la demande (ce qui arrivera quand l'utilisateur les défera).

0

Merci pour votre réponse Jared, ce dont j'ai besoin est de montrer toutes les rues dans un UITableView et laisser l'utilisateur filtrer la recherche dans un UISearchBar ou le laisser simplement le sélectionner de la liste. J'ai changé ma requête à

SELECT DISTINCT(street) from streets 

Ce retour a 3000 lignes résultat, mais il faut en même temps que sans DISTINCT, qui est de 90 sec. J'ai aussi essayé avec "GROUP BY street", pas d'avantages. Cependant si j'ajoute .. LIMIT 3000 le résultat est instantané. J'imagine que la requête doit se déplacer dans toute la table pour obtenir les valeurs DISTINCT, ce qui ne se fait pas avec LIMIT, cela peut-il être une question d'INDEX? Comment savoir si l'index fonctionne? Merci encore!

+0

En ce qui concerne l'optimisation SQL va, je n'ai aucune idée, mais c'est fondamentalement un problème distinct –

3

Si vous avez 250 000 lignes avec seulement 3 000 résultats distincts, chaque rue est dans la base de données 83 fois en moyenne. Peut-être conviendrait-il de séparer vos rues en une table normalisée distincte, chaque valeur n'apparaissant qu'une seule fois, puis de référencer ces rues à partir de votre table d'adresses par ID. Ensuite, pour votre TableView, vous pouvez retirer uniquement les valeurs de votre table Streets.

Comme cela a été mentionné précédemment, vous pouvez également avoir un problème de paradigme de l'interface utilisateur. Si vous avez une table avec 3000 entrées dans l'interface utilisateur, cela pourrait être très fastidieux pour l'utilisateur. (Imaginez que vous essayez de faire défiler un film à la fois vers la rue Yabar.)

Vous pouvez charger au moins paresseusement la table, comme cela a été suggéré précédemment. Ou peut-être pouvez-vous permettre à l'utilisateur de taper un nom de rue, et fournir une interface de type suggérer de Google, surgissant des correspondances potentielles pendant qu'elles tapent.

+0

désolé je n'ai pas vu cette réponse, je vais essayer la chose de normalisation. Merci Jason – user345711