IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes MySQL Discussion :

Compteur de vues : table séparée ou interne table générale?


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    Ingénieur développement de composants
    Inscrit en
    Novembre 2007
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meuse (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur développement de composants
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 34
    Points : 40
    Points
    40
    Par défaut Compteur de vues : table séparée ou interne table générale?
    Bonjour, je préviens, je ne suis pas un spécialiste en SQL... mais pas newbie non plus.

    Je cherche la meilleure solution pour gérer un compteur de 'vues' (nombre de vues d'une fiche/table).

    Actuellement, le champ 'compteur de vues' est dans la table générale avec toutes les informations spécifiques à afficher. Les mises à jour de ce compteur sont donc nombreuses (sur un site qui tourne pas trop mal...). Mais en terme de performance, je me demande s'il ne serait pas plus judicieux de gérer ce compteur de visites/lectures dans une table séparée afin de minimiser les UPDATE sur la "grosse" table.

    Le type de requête se passe ainsi pour l'instant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE latable SET counter = counter+1 WHERE ID = $ID
    et juste ensuite (3 petits points pour simplifier - plus de 30 champs en tout sur plusieurs tables concernées):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT ID,terme,champx1,champx2,...,champx25, counter, champx26,... FROM latable WHERE ID = $ID
    Le champ 'counter' est de type INT 8 non null unsigned avec valeur par défaut à 0 : il y a peut-être déjà quelque chose à optimiser de ce côté? Un MEDIUMINT (quelle taille?) devrait suffire pour quelques temps... (des pages sont à plus d'1 million de vues)

    Comme ce champ counter est dans la table générale, la table est mise à jour "constamment" et je pense que ça dégrade les perfs. Le reste des champs est mise à jour une fois de temps en temps (très long temps... ).

    Ne serait-il pas plus rapide de créer une table annexe qui ne dispose que deux champs : ID et counter? Avec un index sur ID et peut-être sur counter, quoique je n'en vois pas l'utilité mais c'est là où les limites de mes connaissances sont atteintes?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE latablecounter SET counter = counter+1 WHERE ID = $ID
    (ainsi, on ne touche pas à 'latable' en écriture)

    puis (je simplifie au max, je n'ajoute pas tous les a.) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT ID,terme,champx1,champx2,...,champx25, champx26,..., b.ID, b.counter FROM latable a, latablecounter b WHERE a.ID = $ID AND b.ID = $ID
    Sur cette dernière requête, il y a peut-être du mieux à apporter aussi.

    Exemple de page : http://www.aquaportail.com/fiche-poi...nio-rerio.html (le compteur de vues est planqué tout en bas, juste avant les commentaires disqus).

    Merci pour vos conseils avisés.
    Merci d'éviter le poisson rouge dans une boule, ces poissons peuvent grandir jusque 25 cm!

  2. #2
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 388
    Points : 19 119
    Points
    19 119
    Par défaut
    Salut anemone-clown.

    Citation Envoyé par anemone-clown
    des pages sont à plus d'1 million de vues
    Ça en fait des clics !

    Donc mettre "smallint unsigned" est une solution possible, car l'amplitude ira de 0 à 16.777.215.
    Sinon, tu peux mettre "integer unsigned dont l'amplitude ira de 0 à 4.294.967.295.
    Mais ce n'est pas cela qui va te faire gagner du temps.

    Citation Envoyé par anemone-clown
    la table est mise à jour "constamment" et je pense que ça dégrade les perfs.
    Je te propose de créer une nouvelle table, mais en la mettant à "engine=memory".
    De ce fait, ce sera une table mémoire, et les performances seront grandement améliorées.
    Il y a une contrainte à cela, tu devras venir régulièrement mettre à jour ta table générale à partir de cette table mémoire.
    Disons deux fois dans la journée, tu fais la mise à jour et tu remets cette table mémoire à vide (par un "truncate table tablememoire").
    Code mysql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    DROP TABLE IF EXISTS `counter`;
     
    CREATE TABLE `tcounter`
    ( `id`         integer  unsigned NOT NULL primary key,
      `counter`    smallint unsigned NOT NULL
    ) ENGINE=Memory
      ROW_FORMAT=COMPRESSED;
    La colonne "id" doit être la même que ta table général, cela va de soi.
    Comment vas-tu récupérer ce "id" ? Il est nécessaire de faire au moins un accès à ta table général.

    Pour la mise à jour de la table général, tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    update     generale as tb1
    inner join tcounter as tb2
    on tb2.id = tb1.id
     
    set tb1.counter=tb1.counter + tb2.counter;
    Code mysql : Sélectionner tout - Visualiser dans une fenêtre à part
    Sur cette dernière requête, il y a peut-être du mieux à apporter aussi.
    Non, car tu viens mettre à jour cette colonne "counter" à partir de la table mémoire.
    Le mieux est de laisser ton select sur une seule table.

    Sinon, on ne fait pas ainsi une jointure entre deux tables. Ca, c'est la vieille écriture !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select tb1.col1, tb2.colz
    from       table01 as tb1
    inner join table02 as tb2
    on tb2.id = tb1.id
    La colonne "tb2.id" n'est pas nécessairement une clef étrangère.
    Par contre, pour des questions de performance, il faut mettre un index sur la colonne "tb2.id".

    53275 lectures. Ce n'est pas très lisible comme compteur. On ne le voit pas très bien dans ta page.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

Discussions similaires

  1. messages multilingues: table unique ou tables séparées
    Par lexsteens dans le forum Langage SQL
    Réponses: 3
    Dernier message: 26/12/2008, 16h50
  2. [Avis] Vue avec union sur plusieurs tables
    Par adiGuba dans le forum Langage SQL
    Réponses: 0
    Dernier message: 22/09/2008, 11h50
  3. Réponses: 6
    Dernier message: 21/02/2008, 12h29
  4. pb vue sur contrainte d'une table donnée
    Par bb5477 dans le forum SQL
    Réponses: 7
    Dernier message: 11/01/2008, 15h47
  5. Créer une vue utf-8 sur une table iso
    Par bankette dans le forum Requêtes
    Réponses: 1
    Dernier message: 13/09/2007, 10h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo