2009-09-08 6 views
1

J'ai une application utilisant SQLite3. Il fonctionne plutôt bien, mais j'aimerais avoir des suggestions sur l'accélération de l'accès SQLite (écriture). La plupart des opérations de base de données écrivent des triplets (int, int, double) de nombres, environ 20-50 triplets par seconde. Il y a une lecture occasionnelle, mais est à peu près aussi rare que les dents de poule (se produit principalement sur le chargement seulement).Optimiser SQLite3 sur iPhone

Est-ce que quelqu'un a des suggestions sur l'optimisation (ou la désimpression du code)? Tous les raccourcis SQLite3 que j'ai manqués? (L'utilisation de CoreData est due à d'autres éléments du programme.)

Je prépare l'instruction st1 pendant l'initialisation. Il est préparé à partir de

const char *sql = "insert into historic values (?, ?, ?)"; 
if (sqlite3_prepare_v2(database, sql, -1, &st1, NULL) == SQLITE_OK) .... 

Cette préparation est à usage unique. L'extrait que j'utilise pour enregistrer est ci-dessous (j'ai supprimé l'erreur de vérification ici pour plus de clarté).

-(BOOL) saveHvalue:(int) fid time:(int) t value:(double) v type:(int) ftype 
{ 
    { 
     sqlite3_bind_int(st1, 1, fid); 
     sqlite3_bind_int(st1, 2, t); 
     sqlite3_bind_int(st1, 3, ftype); 

     sqlite3_step(st1); 
     sqlite3_reset(st1); 
     sqlite3_clear_bindings(st1); 
    } 

    return YES; 
} 

Répondre

8

Etes-vous en train de grouper les écritures dans une transaction? Cela seul vous fera économiser beaucoup de temps; vous ne pouvez pas les regrouper tous en une seule transaction ou le journal sera gigantesque, mais une transaction par 500-1000 insertions accélérera énormément votre code.

+0

Je vais essayer. Merci. –

+0

Cela a amélioré ma vitesse par des ordres de grandeur !! Merci! –

+0

Bien sûr, si vous traitez 500 enregistrements à la fois et que vous insérez 50/sec, vous perdez (au plus) 10 secondes de données (je pense que les transactions non validées sont annulées si elles sont trouvées dans le journal?); mais cela pourrait ne pas être un gros problème pour votre application. – lapo

0

Est-ce que l'une de vos colonnes dans historic a des index? Si c'est le cas, il est généralement plus rapide de supprimer l'index, d'insérer vos éléments, puis d'ajouter de nouveau l'index (si vous ajoutez un LOT en une seule fois).

+0

Il est également généralement inutile d'avoir des index si tout ce que vous indexez est le PK (et puisque votre base de données est très lourde, je dirais que vous n'avez pas besoin d'index) –

+0

La clé primaire est (fid, t) . –

0

Je ne réponds généralement jamais aux discussions d'habitude mais cela a fonctionné des merveilles pour moi (après des jours essayant d'optimiser dans d'autres secteurs)!

Fondamentalement, j'enveloppées ma boucle d'inserts avec:

sqlite3_exec(db, "BEGIN", 0, 0, 0); 

for() { 
-- inserts -- 
} 

sqlite3_exec(db, "COMMIT", 0, 0, 0); 
+1

Ouais, c'est la "Transaction" mentionnée dans la réponse de @ Paul. –