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

Langage SQL Discussion :

Lenteur de requêtes


Sujet :

Langage SQL

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 6
    Points : 2
    Points
    2
    Par défaut Lenteur de requêtes
    Bonjour,

    Je possède deux tables. L'une contenant des news et l'autre permettant de savoir si un administrateur a vu ou non la news.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    CREATE TABLE `news` (
      `id` int(11) NOT NULL auto_increment,
      `user_id_posteur` int(11) NOT NULL default '0',
      `Message` text NOT NULL,
      `Titre` varchar(50) NOT NULL default '',
      `SourceNom` varchar(105) NOT NULL default '',
      `SourceUrl` text NOT NULL,
      `Date` int(11) NOT NULL default '0',
      `nb_vu` varchar(40) default NULL,
      `concerne` varchar(255) NOT NULL default '',
      `last_modif` int(11) NOT NULL default '0',
      `user_last_modif` int(11) NOT NULL default '0',
      PRIMARY KEY  (`id`)
    )
     
     
    CREATE TABLE `news_admin` (
      `user_id_admin` int(11) NOT NULL default '0',
      `news_id` int(11) NOT NULL default '0',
      `etat` int(11) NOT NULL default '0'
    )
    Le but est le suivant :

    - Si une nouvelle news est entrée dans la table news, je pourrai être averti car il n'y a pas d'infos dans news_admin correspondant à l'id de la news ajoutée.
    - Pour noter comme vu une news, il suffit d'ajouter dans la table news_admin l'id de la news avec l'état '1' (j'ai arbitrairement choisi 1).
    - Lorsqu'une personne modifie une news, il suffit de mettre les champs etat à '2' pour la news correspondante.

    Je souhaite à présent afficher toutes les nouvelles news et les news modifiées pour l'administrateur numéro 2. Il y a une nouvelle news et une news modifiée pour cet admin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    SELECT n.id, n.Titre, n.last_modif, a.etat
    FROM news_admin a
           RIGHT OUTER JOIN news n
                  ON a.news_id = n.id
                         AND a.user_id_admin = 2
     
    1 905 total, traitement: 0.1533 sec
    > 1903 etat à 1
    > 1 etat à 2
    > 1 etat à NULL
     
     
    SELECT n.id, n.Titre, n.last_modif, a.etat
    FROM news_admin a
           RIGHT OUTER JOIN news n
                  ON a.news_id = n.id
                         AND a.user_id_admin = 2
    WHERE etat = 2
     
    1 total, traitement: 0.0039 sec
    > 1 etat à 2
     
     
    SELECT n.id, n.Titre, n.last_modif, a.etat
    FROM news_admin a
           RIGHT OUTER JOIN news n
                  ON a.news_id = n.id
                         AND a.user_id_admin = 2
    WHERE etat = 2 OR etat IS NULL
     
    2 total, traitement: 10.2352 sec
    > 1 etat à 2
    > 1 etat à NULL

    J'arrive effectivement avec la dernière requête a extraire la news ajoutée et la news modifiée, mais le temps de traitement est de 10 secondes !

    Si j'utilise la première requête et que je fais le tri des résultats en php (c'est-à-dire que je ne garde que les état NULL ou égalent à 2) c'est aussi très long.

    Quelqu'un sait pourquoi cela prend autant de temps de tester simplement un IS NULL sur le champs etat ? Je ne comprends pas cet écart de temps de traitement...

  2. #2
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir,


    Avez-vous exécuté un EXPLAIN afin de voir si le SGBD utilise les index de façon satisfaisante (s'ils existent) ?

    Par ailleurs, avec un RIGHT OUTER JOIN, vous récupérez toutes les lignes concernées. Un test d'existence (WHERE ... EXISTS...) serait a priori plus économique.

    Au passage, la table news_admin n'a ni clé primaire ni clés étrangères ?


    N.B. Pour le confort des lecteurs, merci d'indenter les requêtes, comme cela est précisé dans la charte DVP :
    la clause SELECT sur une ligne, la clause FROM sur une autre, etc.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    J'ai suivi votre conseil et ai ajouté une clé à la table news_admin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    CREATE TABLE `finaland_news_admin` (
      `user_id` int(11) NOT NULL default '0',
      `news_id` int(11) NOT NULL default '0',
      `etat` tinyint(1) NOT NULL default '0',
       KEY `i_userid_newsid` (`user_id`,`news_id`)
    );

    Voici à présent les temps de traitement pour les requêtes respectivements citées dans mon premier message :

    1 905 total, traitement: 0.0040 sec.
    1 total, traitement: 0.0107 sec
    2 total, traitement: 0.0226 sec.

    Me voilà sauvé, j'ai divisé par 500 le temps de traitement de la dernière requête (celle qui m'intéressait !)


    Pour répondre à vos questions :

    - J'ai trouvé un site qui explique comment faire un EXPLAIN, mais la création de la table a échoué. Je n'ai pas cherché plus loin dans cette voie.

    - Pourriez-vous m'expliquer pourquoi un WHERE...EXISTS serait-il plus efficace qu'une jointure externe ?

    - Toutes mes excuses pour l'indentation, je vais modifier cela de ce pas ^^

  4. #4
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut EXPLAIN
    Bonsoir,

    Citation Envoyé par Dragonflash Voir le message
    Me voilà sauvé, j'ai divisé par 500 le temps de traitement de la dernière requête
    Sauvé, du moins pour cette fois-ci. Mais il n'est pas dit que pour d’autres requêtes, vous ne retrouviez pas à nouveau des problèmes de performance.

    Citation Envoyé par Dragonflash Voir le message
    J'ai trouvé un site qui explique comment faire un EXPLAIN, mais la création de la table a échoué. Je n'ai pas cherché plus loin dans cette voie.
    Je vous engage néanmoins vivement à étudier cette instruction, ne serait-ce que pour comprendre très vite pourquoi votre SGBD rame pour telle ou telle requête.

    Citation Envoyé par Dragonflash Voir le message
    Pourriez-vous m'expliquer pourquoi un WHERE...EXISTS serait-il plus efficace qu'une jointure externe ?
    En fait, EXISTS vaut pour la jointure interne. Quand vous posez la question suivante au SGBD : « Est-ce qu’il y a du courrier pour Tartempion ? » en utilisant la clause EXISTS, un SGBD normalement constitué dira une seule fois oui dès qu’il en aura trouvé et ne cherchera pas à pousser plus loin ses investigations. En revanche, avec la jointure, il dira oui, oui, oui, ... autant de fois qu’il trouvera du courrier. Maintenant, si vous voulez tout savoir sur chacun de ces courriers, vous joignez. Pour savoir objectivement quelle requête est la plus appropriée : EXPLAIN.

    Concernant la jointure externe, le pendant est NOT EXISTS. En cas d'absence de courrier pour Tartempion, la réponse sera encore une fois unique, au lieu de redonder n fois. A nouveau, si vous voulez tout savoir sur chacun de ces courriers, vous joignez. Pour savoir objectivement quelle requête est la plus appropriée : toujours et encore EXPLAIN.


    Et, beaucoup plus important, n’oubliez pas de définir les clés étrangères pour la table finaland_news_admin, afin de ne pas vous retrouver avec des références a des news et des users inconnus au bataillon.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

Discussions similaires

  1. lenteur de requête mysql vers un poste windows
    Par richard dev dans le forum Réseau
    Réponses: 3
    Dernier message: 08/06/2009, 11h09
  2. AjaxAnywhere et la lenteur des requètes !
    Par eric95 dans le forum Bibliothèques & Frameworks
    Réponses: 5
    Dernier message: 22/12/2008, 03h21
  3. Problème de lenteur avec requêtes MySql en réseau local
    Par marcootz dans le forum Requêtes
    Réponses: 2
    Dernier message: 08/11/2007, 14h07
  4. [Python+PostgreSQl] lenteur de requêtes
    Par guestCam dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 08/08/2007, 13h41
  5. Lenteur de requête pour afficher une image
    Par bobobobo01 dans le forum WinDev
    Réponses: 2
    Dernier message: 20/07/2007, 15h22

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