Sqlite à pour politique de ne pas stocker de meta data à propos du nombre de ligne des tables. C’est un choix justifiable car garder ces infos pour toutes les tables est couteux en ressources et ralenti donc forcément chaque INSERT/DELETE.
Parcourir une table lors du COUNT n’est donc pas très problématique sauf quand les tables atteignent un niveau important de données.
Mauvaise surprise pour moi lorsque ma page à mis plus de 1 min à s’afficher (base de 7Go et 500k enregistrements).
Pour résoudre le problème il faut émuler cette meta data avec 2 triggers et une tables supplémentaire.
On pourra par exemple créer une table « totaux » avec 3 champs « id », »table » et « valeur ». Il y’aura donc un enregistrement par table avec pour valeur le nombre de lignes de cette table.
Ne reste qu’à creer les deux triggers :
CREATE TRIGGER "count_delete_matable" AFTER DELETE ON maTable BEGIN UPDATE totaux SET valeur = valeur-1 WHERE table='maTable'; END;CREATE TRIGGER "count_insert_matable" AFTER INSERT ON maTable BEGIN UPDATE totaux SET valeur = valeur+1 WHERE table='maTable'; END;
Ainsi après chaque enregistrement ajout ou supprimer le total sera automatiquement in/decrémenté.
Ne reste en suite qu’à remplacer les
SELECT COUNT(*) FROM maTable
par
SELECT valeur FROM totaux WHERE table='maTable'
Et là Ô magie , la page passe de plus d’1min à moins d’une demi seconde 🙂