dimanche 7 février 2010

Créer une table coûte cher...

Pour mon serveur de logs, j'ai utilisé le système suivant pour écrire un message dans la base Postgresql:

  • Ouvrir la transaction

  • Créer une table temporaire qui sera détruite automatiquement à la fin de la transaction (on commit drop)

  • Remplir la table avec les éléments de mon message

  • Appeler la fonction qui va cŕeer les entrées dans les tables, à partir de la table temporaire

  • Fermer la transaction, causant la destruction de la table temporaire.

Pour tester un peu tout ceci, j'ai envoyé 10000 messages de log d'un coup. Grosse déception, les performances étaient vraiment ridicules, à environ 60 messages par seconde.

J'ai ensuite réessayé en changeant le mécanisme pour la table temporaire: cette fois-ci, je créé la table une seule fois, au tout début, et je dis à Postgres de se contenter de tronquer la table à la fin de la transaction (on commit delete rows).

Surprise, la base de données s'en trouve beaucoup mieux, et pédale à 600 transactions par seconde!

Autant qu'il soit agréable qu'il ait été si simple de décupler ainsi les performances, je ne suis pas tout à fait satisfait par cette solution. Le problème principal est de gérer les reconnections: comment détecter que la table a disparu, et comment la recréer?

J'ai donc changé mon code de manière à appeler, pour chaque transaction, une fonction qui va détecter si la table existe déjà, et si non la créé. Vivement les blocks anonymes (DO $$ ... $$), mais ce sera pour Postgresql 8.5 (ou plutôt, Postgresql 9.0, puisque c'est ainsi que la prochaine version s'appelle désormais).

Verdict: 400 transactions par secondes. Et une routine qui sera imperméable aux déconnections. Ça me va!

Aucun commentaire: