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 :

Requête très longue à charger


Sujet :

Requêtes MySQL

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Août 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : Transports

    Informations forums :
    Inscription : Août 2014
    Messages : 11
    Points : 6
    Points
    6
    Par défaut Requête très longue à charger
    Bonjour,

    j'ai monté un site, ou le but est de voir des profils de gens uns par uns.

    Mais dès que l'utilisateur A voit l'utilisateur B, il ne doit plus pouvoir le revoir après, donc j'ai une table "membres_vus" ou j'inscris le pseudo de l'utilisateur qui a vu, et le pseudo de l'utilisateur vu.

    Et pour afficher les profils, j'utilise cette requête:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT *
    FROM users
    WHERE users.login NOT IN (SELECT membres_vus.to FROM membres_vus WHERE membres_vus.from = "'.$_SESSION['login'].'")
    ORDER BY RAND()
    Mais la page est vraiment très très longue à charger, environ 30 secondes avec une bonne connexion... Au début il n'y avait que quelques dizaines de profils donc ça allait, mais maintenant il y a 1200 profils et plus de 50 000 vus...

    Comment faire pour avoir le même système mais qui rame moins?

    Merci d'avance,

    Lucas

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    La page est longue a charger ou bien la requête est longue a executer ?
    Ce n'est pas pareil.
    Tu nous parles de "bonne connexion" mais la vitesse de connexion n'intervient pas dans l'execution d'une requête.
    Donc il faudrait déjà identifier le point lent.

    Tout de même : ORDER BY RAND() n'est pas efficace sur de grandes quantités de données.
    Contrôle que le problème ne soit pas seulement là.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Août 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : Transports

    Informations forums :
    Inscription : Août 2014
    Messages : 11
    Points : 6
    Points
    6
    Par défaut
    La lenteur vient bien de la requête et non pas de la page, et le problème ne vient pas de la fonction RAND() j'ai essayé

  4. #4
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Quel est le temps d'execution de la sous requête ?
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  5. #5
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Points : 16 372
    Points
    16 372
    Par défaut
    Tu as essayé ta requête directement sur la base (avec PhpMyAdmin ou assimilé) ?
    Quel SGBD utilises-tu ? ya-t-il des index ?
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Août 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : Transports

    Informations forums :
    Inscription : Août 2014
    Messages : 11
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par sabotage Voir le message
    Quel est le temps d'execution de la sous requête ?
    Le temps d'éxecution de ma requête est de 19 secondes.

    Citation Envoyé par Celira
    Tu as essayé ta requête directement sur la base (avec PhpMyAdmin ou assimilé) ?
    Quel SGBD utilises-tu ? ya-t-il des index ?
    Oui, j'ai essayé ma requête directement depuis ma base (cf. ci-dessus)
    Mon SGBD est MySQL (SGBD de easy-hebergement.net)

  7. #7
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2010
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 144
    Points : 241
    Points
    241
    Par défaut
    Si il y a beaucoup de champs sur la table "users", le "SELECT *" de ta requête peut être remplacé par la liste des champs que tu as besoin de récupérer.
    Est-ce que tu as besoin de récupérer tous les membres d'un seul coup (soit 1200 profils pour un nouvel user...) ? Si non tu peux ajouter un "LIMIT <nb_membre_a_recuperer>" a la fin de ta requête.

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Août 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : Transports

    Informations forums :
    Inscription : Août 2014
    Messages : 11
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par gmarsay Voir le message
    Si il y a beaucoup de champs sur la table "users", le "SELECT *" de ta requête peut être remplacé par la liste des champs que tu as besoin de récupérer.
    Est-ce que tu as besoin de récupérer tous les membres d'un seul coup (soit 1200 profils pour un nouvel user...) ? Si non tu peux ajouter un "LIMIT <nb_membre_a_recuperer>" a la fin de ta requête.
    J'ai tout essayé, rien ne marche.. Le problème vient du nombre d'entrées dans la table membres_vus. Quelqu'un m'a parlé d'indexation des données? J'ai essayé de me renseigner mais je ne suis pas expert en PHP, je ne comprends pas vraiment..

  9. #9
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Le temps d'éxecution de ma requête est de 19 secondes.
    Pas la requête entière, seulement la sous-requête.

    Dans tous les cas ta requête serait beaucoup plus rapide si tu travaillais avec des id numériques et pas avec des logins.
    Dans ta table "users" l'index devrait être un id numérique autoincrementé.
    Dans membres_vus on aurait cet id au lieu du login.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  10. #10
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Je pense qu'une bonne partie de la lenteur vient du fait que ta base est mal conçue. Au lieu de faire une table dans laquelle les logins sont répétés x fois pour chaque relation (ce qui prend de la place et n'est pas rapide), tu devrais plutôt utiliser les index de chaque login, exemple:

    table: user
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    id | login          | champ1  | champ2 ...
    -----------------------------------------------
     1 | Robert
     2 | Norbert
     3 | Gilbert
     4 | Philibert
    ...
    table: membres_vus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    id | id_user | id_user_vu
    -------------------------------
     1 |       4 |          2
     2 |       2 |          1
     3 |       1 |          2
     4 |       4 |          3
    ...
    En faisant ça, au lieu de comparer des chaînes de caractères MySQL n'aura que des nombres à comparer, ce qui est plus rapide (et prend moins de place).
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  11. #11
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par LucasB16 Voir le message
    Quelqu'un m'a parlé d'indexation des données? J'ai essayé de me renseigner mais je ne suis pas expert en PHP, je ne comprends pas vraiment..
    Pour votre requête, vous pouvez placer cet index :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CREATE UNIQUE INDEX UIX_VU ON membres_vus (FROM, TO)
    Mais idéalement, il faudrait commencer par appliquer ce qui a déjà été dit, notamment l'utilisation d'identifiants numériques en lieu et place des logins.

  12. #12
    Futur Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Août 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : Transports

    Informations forums :
    Inscription : Août 2014
    Messages : 11
    Points : 6
    Points
    6
    Par défaut
    Merci à tous pour vos réponses!!!

    Citation Envoyé par CosmoKnacki Voir le message
    Je pense qu'une bonne partie de la lenteur vient du fait que ta base est mal conçue. Au lieu de faire une table dans laquelle les logins sont répétés x fois pour chaque relation (ce qui prend de la place et n'est pas rapide), tu devrais plutôt utiliser les index de chaque login, exemple:

    table: user
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    id | login          | champ1  | champ2 ...
    -----------------------------------------------
     1 | Robert
     2 | Norbert
     3 | Gilbert
     4 | Philibert
    ...
    table: membres_vus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    id | id_user | id_user_vu
    -------------------------------
     1 |       4 |          2
     2 |       2 |          1
     3 |       1 |          2
     4 |       4 |          3
    ...
    En faisant ça, au lieu de comparer des chaînes de caractères MySQL n'aura que des nombres à comparer, ce qui est plus rapide (et prend moins de place).
    Merci beaucoup, ça m'éclaire énormément!
    Dois-je mettre des index pour les champs id_user & id_user_vu?

  13. #13
    Futur Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Août 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : Transports

    Informations forums :
    Inscription : Août 2014
    Messages : 11
    Points : 6
    Points
    6
    Par défaut
    up

  14. #14
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Je ne vois pas l’intérêt de la colonne id dans la table membres_vus.

    Vous indiquez qu'un ne peut en voir un autre qu'une seule fois. Définissez donc le couple (id_user , id_user_vu) comme clef primaire, ce qui créera automatiquement l'index nécessaire à votre requête.

  15. #15
    Futur Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Août 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : Transports

    Informations forums :
    Inscription : Août 2014
    Messages : 11
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    Je ne vois pas l’intérêt de la colonne id dans la table membres_vus.

    Vous indiquez qu'un ne peut en voir un autre qu'une seule fois. Définissez donc le couple (id_user , id_user_vu) comme clef primaire, ce qui créera automatiquement l'index nécessaire à votre requête.
    D'accord!

    Ma table est-elle bien conçue à présent? Les champs "id_membre" et "id_membre_vu" ont un Index "Primary"

  16. #16
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    bonjour,

    non.
    Une date cest une date et non un big int

  17. #17
    Futur Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Août 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : Transports

    Informations forums :
    Inscription : Août 2014
    Messages : 11
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par punkoff Voir le message
    bonjour,

    non.
    Une date cest une date et non un big int
    Oui, mais la date est notée en timestamp

  18. #18
    Membre averti
    Profil pro
    Administrateur
    Inscrit en
    Mai 2008
    Messages
    237
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Administrateur
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2008
    Messages : 237
    Points : 433
    Points
    433
    Par défaut
    Vu que le Where est appliqué sur id_user le meilleur index sera id_user, id_user_vu et non id_user_vu, id_user

    Essayez les requêtes suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT u.id, u.login
    FROM users u
    WHERE u.id NOT IN (SELECT id_user_vu FROM membres_vus WHERE id_user = '.$user_id . ')
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT u.id, u.login
    FROM users u
    INNER JOIN membres_vus v ON v.id_user NOT IN ('.$user_id . ') AND u.id = v.id_user_vu

Discussions similaires

  1. Page très longue à charger
    Par night_flyers dans le forum Requêtes
    Réponses: 0
    Dernier message: 11/07/2009, 14h54
  2. Requête très longue sur une table très simple
    Par kragenskul dans le forum Requêtes
    Réponses: 6
    Dernier message: 16/06/2009, 14h28
  3. Une requête très longue à l'exécution
    Par mouaa dans le forum Langage SQL
    Réponses: 8
    Dernier message: 30/05/2008, 07h57
  4. Requête très longue à éxécuter
    Par pisoka000 dans le forum Requêtes
    Réponses: 4
    Dernier message: 02/05/2007, 11h31
  5. Réponses: 4
    Dernier message: 09/12/2005, 08h25

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