Sqlite : optimiser un COUNT() long

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 🙂

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *