[SQL] Optimisation, vue ou trigger?

Hello,

Donc aujourd’hui j’ai une question d’optimisation de base de données (mysql). J’ai une table “test” d’environ 50000 enregistrements contenant les champs “a” et “b” et un troisième champ “c” dépendant d’une formule mathématique vraiment triviale en fonction de “a” et “b”.

Le problème: Je dois souvent faire des sélections sur cette valeur “c”. J’ai donc opté pour une solution à base de triggers: lors d’un insert ou d’une modification, je mets à jour la valeur de “c” en fonction de “a” et “b”, et cela me permet d’indexer le champ “c”.

Mais une autre solution se profile à moi: pourquoi ne pas simplement faire une vue basée sur la table “test” et contenant le champ supplémentaire? C’est certainement plus rapide lors des modifications et des insertions, mais pour les sélections, je crains que les performances soient fortement grêvées.

La question que je me pose donc est: ai je réellement fait le bon choix avec mon trigger?

Je vais peut-être dire une bêtise, mais la règle qu’on m’a apprise en cours de SGBD c’est « Ne jamais mettre dans une table un champ dont la valeur peut être calculée en fonction des valeurs d’autre champs de la table ».

Si le calcul est simple => requête SQL
Si le calcul est complexe => tu crées une vue

Je serai curieux de lire vos réponses :slight_smile:

Lupuss: oui, je pense que c’est toujours valable: si c’est calculable, ne pas le mettre en dur… Enfin y’a pas qu’en SGBD, je dirais en prog en général :slight_smile:

Sauf qu’a haute frequence, le retrieve (ou caching hein) peut etre plus efficace que le calcul. Perso, si c’est vraiment trivial, je le cacherais en memoire plutot qu’en DB.

Sauf que si vous le calculez au moment du select where calcul(a et b ), le SGBD va calculer la totalité des lignes pour faire son select. Donc ça revient à faire une vue complète avant chaque requête.

Maintenant, ton trigger c’est du code métier. Que fout du code métier dans un sgbd ?? Tu devrais calculer ton champ c dans ton code avant l’insert/update du row concerné. 1) ca ira plus vite (tout est plus rapide qu’un trigger) 2) c’est pas dépendant de la BDD (tu passes en mongo ou en mysql <5.1 tu fais quoi ?)

Sinon triggger si tu ne peux pas le mettre dans ton code mais c’est pas une “belle” solution

[quote=« Donjohn, post:5, topic: 53625 »]Que fout du code métier dans un sgbd ??
[/quote]C’est pas le but des procédures stockées justement (pas taper, ça fait un moment que j’ai plus fait de design de BD :slight_smile: ) ?

depuis tout à l’heure, je me cache sous le bureau à 4 pattes en faisant grouik, grouik :smiley:

Moi je mets tout en procédure stocké (pas taper ) ce qui m’a déjà sauvé la vie

[quote=« ElRed, post:7, topic: 53625 »]
depuis tout à l’heure, je me cache sous le bureau à 4 pattes en faisant grouik, grouik :smiley:
[/quote]Tu te prends pour la secrétaire? :ninja:

Si, entre autre, c’est des triggers dont le code est pré-compilé (je simplifie, me tapez pas Mrs les DBA ;)).

A part des SGBD à ouatemille euros la licence, les perfs des procédures stockés c’est juste de la MERDE. Donc si t’es pas sur du MS-SQL, Oracle, etc… tu bannis les procédures stockés.

en plus, niveau organisation du code, avoir du code métier sur différents systèmes : c’est mal :wink:

Perso, le max que j’avais en trigger ou procedure stockées, c’etait des MAJ d’index ou des MAJ de timestamp d’update/creation sur les lignes. Jamais plus.

Moi je ferai le calcul au même moment que l’INSERT ou l’UPDATE

Pareil, je mettrai ça dans Redis

C’est meme pas des triggers ca, ce sont des mecanismes auto de BDD. Ca ressemble à un trigger dans les faits mais ca n’en est pas un dans le core du sgbd.

les cascade ondelete etc… c’est pas des triggers non plus

Evenement != trigger mais un trigger se declenche sur un evenement.

Je chipotte je sais :wink:

C’est même evident :wink:
Apres on a pas toujours toutes les libertés donc les triggers peuvent « parfois » etre une solution (dans le cas présent, pas trop ;))

Question bête : si le champ “c” est fait avec un calcul vraiment trivial, n’est-t-il pas possible de faire un index sur ce calcul plutôt que de le stocker dans un champ “c” ?

Edit : Apparemment ce n’est pas encore supporté sur Mysql, dommage…

Edit2 : Voilà un lien qui peut t’intéresser, finalement le trigger (ou l’update manuel) est la seule solution pour avoir un index sur ton calcul. Dans la version 6 de Mysql il existera une solution plus élégante avec les colonnes virtuelles.
http://integration.gold-solutions.com/page.php

Sinon la vue ne répond pas à ton besoin car les indexes ne peuvent pas y être ajoutés, sauf si tu fais une vue matérialisée, par contre je me demande si on n’est pas obligé de créer un trigger pour l’alimenter donc on se mord un peu la queue.

Les triggers c’est le mal. LE MAL.
Autant les sprocs… on peut discuter, autant les triggers, c’est pas ouvert a nego: c’est le mal.

tu peux développer ?

LOL …

En gros les problèmes que j’ai déjà rencontré avec des triggers sont qu’ils ne sont pas fiables à 100%, il est déjà arrivé là où je bosse qu’ils se soient arrêtés de fonctionner.

En plus de ça, il y a un gros problème de lisibilité du code car il n’y a pas de relation directe dans le code entre les modifications de la table et l’action du trigger.

Par contre l’avantage qu’il y a est que ça évite de faire des modifications dans tous les endroits du code où les modifications de la table sont faites. En général on propose le trigger pour donner une solution rapide à un problème tout en planifiant de refaire la même modification manuellement.

Après il y a des cas où le choix du trigger est très bien, par exemple lorsqu’on veut tracer les modification de certaines tables, on peut activer les triggers correspondants.