[mySQL] Découper une table et gagner en performance ?

Discussion dans 'Développement d'un site Web ou d'une appli mobile' créé par thunderfear, 9 Janvier 2010.

  1. thunderfear
    thunderfear WRInaute discret
    Inscrit:
    12 Octobre 2004
    Messages:
    50
    J'aime reçus:
    0
    Bonjour,

    J'ai besoin d'un conseil concernant la découpe d'une table. (en vue de la rendre moins lourde et de l'accélérer)

    Ma table est assez lourde et certains champs ne sont pas utilisés par tous les enregistrements.

    Exemple: Chaque enregistrement possède un champs description (type TEXT) mais ce champs est facultatif donc pour la moitié des enregistrements ce champs est vide.

    Est-ce que je gagnerai beaucoup en performance si j'enleve le champs description de la table pour la mettre dans une autre table.

    Cette technique diminuerai surement la taille de la table mais cela ajouterai une jointure en plus lorsque je ferai un select.

    Qu'en pensez-vous?

    Merci

    A bientôt.
     
  2. screuscreu
    screuscreu WRInaute impliqué
    Inscrit:
    14 Janvier 2008
    Messages:
    687
    J'aime reçus:
    0
    elle est lourde comment ? Car si c'est pour diviser 1000 enregistrements en 2x 500 moi je dis non.
    En fait je suis pas sûr dans tous les cas qu'il y ait une bonne raison.

    Jacques, si tu passes par là, on a besoin de tes compétences !
     
  3. thunderfear
    thunderfear WRInaute discret
    Inscrit:
    12 Octobre 2004
    Messages:
    50
    J'aime reçus:
    0
    Pour le moment, elle fait 110 Mo pour 80 000 enregistrements.
     
  4. raljx
    raljx WRInaute passionné
    Inscrit:
    10 Juillet 2006
    Messages:
    2 022
    J'aime reçus:
    0
    dans le cas de plusieurs centaines de milliers d'enregistrements (plusieurs millions même) la séparation de données texte et numériques est une très bonne chose. L'ajout d'un ID (INT) dans la première table ramenant sur les données TXT de la 2eme est la solution la plus simple a mettre en place... un bon INDEX sur la 2eme et le tour est joué, les gains de performance (surtout s'il y a de nombreux SELECT n'est carrement pas négligeable . Dans le cas d'une table avec très peu d'enregistrement je ne suis cependant pas sur qu'en terme de vitesse tu ne perdrais pas quelques ms...
     
  5. jcaron
    jcaron WRInaute accro
    Inscrit:
    13 Février 2004
    Messages:
    2 579
    J'aime reçus:
    0
    Pas un grand spécialiste de la façon dont mySQL fait ça (moi je suis plutôt Postgresql), et ça doit en plus varier suivant que tu utilises du myIsam ou du InnoDB, mais quelques pistes:
    - si toute ta base tient en RAM en permanence et que tu fais surtout des lectures et éventuellement des ajouts (mais pas de modifs), ça ne devrait rien changer
    - si tu as beaucoup de modifs (sur les champs autre que le "gros" champ texte), il peut en effet être utile de séparer les deux (dans un environnement ACID il est nécessaire de faire des copies de la ligne complète à chaque modif, ce qui veut dire qu'il y aura beaucoup d'accès disque)
    - ça dépend probablement pas mal de la taille de tes champs texte
    - ça dépend aussi des accès que tu fais. Si tu as les bons index et que toutes les requêtes les utilisent, ça ne devrait pas changer grand chose. Si par contre les requêtes que tu effectues n'utilisent pas d'index, ça peut faire une différence non négligeable (vu qu'il faut qu'il lise toute la table pour trouver les bons enregistrements, plus la table à lire est petite, mieux c'est). Evidemment si c'est une recherche genre LIKE '%toto%' sur le champ texte, ça ne va rien changer.
    - ça dépend aussi du fait que tu aies besoin du champ en question à chaque requête ou pas, et dans le deuxième cas, de la proportion des requêtes qui en ont besoin ou pas...

    Bref, réponse de normand, ptet ben qu'oui, ptet ben qu'non, ça dépend. En ce qui me concerne, pour une table de cette taille, si tu n'as pas un serveur sérieusement sous-dimensionné, je ne m'embêterais pas trop, mais je m'assurerais quand même qu'il y a les bons index et qu'ils sont utilisés.

    Jacques.
     
  6. thunderfear
    thunderfear WRInaute discret
    Inscrit:
    12 Octobre 2004
    Messages:
    50
    J'aime reçus:
    0
    Merci pour vos messages.

    Je pense que je vais attendre avant de séparer la table.

    @+ tard
     
  7. Julia41
    Julia41 WRInaute passionné
    Inscrit:
    31 Août 2007
    Messages:
    1 774
    J'aime reçus:
    0
    As-tu testé d'autres moteurs de stockage ?
    innoDB, voir memory (attention, si t'as un crash tu perds tout donc backup fréquent).

    En innoDB, tu ne pourras pas faire d'INDEX de type FULLTEXT, la technique est donc de balancer ces fulltext dans une autre table qui n'est "tappé" que quand c'est vraiment nécessaire.

    Si ta table (par exemple "user") prends aussi en compte, en bas de chaque page un champ "last visit" tu peux "cacher" cette valeur :
    Code:
    if (!$memcache->get('lastvisit' . $userid)) {
    $sql = 'update user set lastvisit = NOW() WHERE id = \'' . $userid . '\';';
    $DB->query($sql);
    $memcache->set('lastvisit' . $userid, 1, 0, 360);
    }
    Code à vérifier mais voilà ce que j'utilisais pour mettre à jour leurs ip/lastvisit etc ;)
    Ca permet d'effectuer cette requête uniquement toute les 360 secondes.

    Pour les visites d'un forum par exemple, tu peux utiliser la même technique avec $memcache->increment. Si ça arrive au dessus de 10, tu rajoutes + 10 au post du forum et donc tu fais 10 fois moins de mises à jour de tables.
     
  8. raljx
    raljx WRInaute passionné
    Inscrit:
    10 Juillet 2006
    Messages:
    2 022
    J'aime reçus:
    0
    Dans le cas du post, (80K enregistrements) je penche ++ pour la separation car :
    -> cela ne prends pas énormément de temps a modifier (dans le cas d'un dev propre)
    -> même si les perfs ne sont pas de suite au rendez-vous --> cela sera un bon saut pour la suite ...

    Manque peut être quelques infos concernant en effet le serveur (dixit jcaron)
     
  9. seebz
    seebz WRInaute impliqué
    Inscrit:
    15 Avril 2007
    Messages:
    722
    J'aime reçus:
    0
  10. Julia41
    Julia41 WRInaute passionné
    Inscrit:
    31 Août 2007
    Messages:
    1 774
    J'aime reçus:
    0
    Si tu es en innoDB, tu peux aussi prendre 10 Disques dur sur ta machine et séparer les IBData en autant de partition que de disques. Là les stats seront au rendez-vous, mais bon, rien ne vaut de l'optimisation au niveau de PHP aussi ;)
     
Chargement...
Similar Threads - [mySQL] Découper table Forum Date
[résolu][mysql] faire un "NOT LIKE" sur une chaîne contenant des / Développement d'un site Web ou d'une appli mobile 25 Octobre 2014
[MySQL] Liste (select) avec des lignes au hasard Développement d'un site Web ou d'une appli mobile 23 Octobre 2014
[MySQL] Requête SELECT et INSERT entre 3 tables liées+Aide Développement d'un site Web ou d'une appli mobile 30 Avril 2014
[MySQL] Nombre d'enregistrements sur des horaires précis Développement d'un site Web ou d'une appli mobile 19 Juillet 2013
[MYSQL] Comment remplacer caractères dans tous les champs de toutes les tables d'une base? Développement d'un site Web ou d'une appli mobile 11 Juillet 2013
[MYSQL] Une sorte de "OR JOIN" ? Développement d'un site Web ou d'une appli mobile 5 Juillet 2013
[MySQL] sélectionner la dernière note pour chaque élève en une seule requète ? Développement d'un site Web ou d'une appli mobile 12 Avril 2012
[Mysql] Requête PDO avec variable php Développement d'un site Web ou d'une appli mobile 16 Février 2012
[Mysql] Requête PDO aléatoire Développement d'un site Web ou d'une appli mobile 7 Février 2012
[MYSQL] Tri par date Développement d'un site Web ou d'une appli mobile 7 Septembre 2011
[MySQL] rechercher une valeur dans un champ sérialisé Développement d'un site Web ou d'une appli mobile 10 Août 2011
[MySQL] Requête SELECT entre 3 tables liées Développement d'un site Web ou d'une appli mobile 10 Août 2011
[MySQL] addslashes et stripslashes Développement d'un site Web ou d'une appli mobile 9 Août 2011
[résolu] [mysql] Conditions WHERE avec AND et OR Développement d'un site Web ou d'une appli mobile 13 Mai 2011
[mysql] trier les résultats d'une requête selon une table non liée à la requête Développement d'un site Web ou d'une appli mobile 15 Avril 2011
[résolu] [mysql] passer un champ à une valeur donnée pour tous les enregistrements Développement d'un site Web ou d'une appli mobile 25 Mars 2011
[MySQL] INSERT / UPDATE conditionnel Développement d'un site Web ou d'une appli mobile 1 Février 2011
[mysql] LIMIT utile sur un champ indexé ? Développement d'un site Web ou d'une appli mobile 8 Décembre 2010
[MySQL] Récupérer la première ligne d'un GROUP BY Développement d'un site Web ou d'une appli mobile 14 Décembre 2009
[MySQL] : select de 2 tables et mysql_fetch_assoc Développement d'un site Web ou d'une appli mobile 22 Septembre 2009