2010-04-23 6 views
3

J'essaie actuellement d'optimiser le processus lent de récupération d'une page d'entrées de journal à partir de la base de données SQLite.Résultats de deux requêtes à la fois dans sqlite?

Je remarqué que je presque toujours récupérer les entrées suivantes avec le nombre d'entrées disponibles:

 SELECT time, level, type, text FROM Logs 
     WHERE level IN (%s) 
     ORDER BY time DESC, id DESC 
     LIMIT LOG_REQ_LINES OFFSET %d* LOG_REQ_LINES ; 

ainsi que le nombre total d'enregistrements qui peuvent correspondre à la requête en cours:

 SELECT count(*) FROM Logs WHERE level IN (%s); 

(pour un affichage " page n de m ")

Je me demande, si je pouvais concaténer les deux requêtes, et leur demander à la fois dans un sqlite3_exec() simplement concaténer la chaîne de requête. Comment devrait alors apparaître ma fonction de rappel? Puis-je distinguer les différents types de données par argc?

Quelles autres optimisations suggérez-vous?

Répondre

2

Vous pouvez faire en sorte que la requête de comptage renvoie le même nombre de colonnes que la requête de sélection et créer un UNION de la requête de comptage et de la requête de sélection.

La première ligne du jeu de résultats contiendra alors le nombre total.

Une autre solution possible est décrite dans the post about SQL_CALC_FOUND_ROWS de sqlite-users maillist.

Et un petit avis concernant votre sélection requête: si vous insérez des enregistrements dans la table journal avec datetime('now') et id est la clé primaire incrémentée automatique de la table, puis le tri par le temps n'est pas nécessaire et il suffit de trier par id DESC . Étant donné que le champ de clé primaire auto incrémentée est un alias à ROWID, vous obtiendrez une amélioration significative des performances. Soit dit en passant, time est une fonction intégrée dans SQLLite, vous devriez donc citer le nom de la colonne avec des back-ticks (`).

+0

En fait, il a d'abord été jugé nécessaire de trier en fonction du temps en raison des changements d'heure d'été et du réglage de l'horloge. Ensuite, il a été jugé définitivement contre-productif (en mélangeant les journaux avant et après le changement d'heure d'été) et a ensuite été mis au rebut. –

1

Vous pouvez utiliser votre requête avec la fonction sqlite3_get_table pour collecter les lignes
et obtenir le nombre de lignes de résultats.

1

Vous pouvez utiliser triggers pour comptabiliser le nombre d'entrées de chaque niveau dans une table distincte. Les déclencheurs doivent incrémenter le compte lorsqu'une entrée est insérée et décrémenter le compte lorsqu'une entrée est supprimée.

Exemple:

create table Log_counts (level primary key, count); 

create trigger Log_insert_trigger after insert on Logs 
    for each row 
    begin 
    update Log_counts set count = count + 1 where level = new.level; 
    end; 

create trigger Log_delete_trigger after delete on Logs 
    for each row 
    begin 
    update Log_counts set count = count - 1 where level = old.level; 
    end; 

Vous devrez initialiser Log_counts avec les comptes par niveau; dans une base de données vide, pour chaque niveau ...

insert into Log_counts (level, count) values (%s, 0); 

vous ne serez pas besoin d'un nombre (*) requête pour chaque page d'affichage.

Questions connexes