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

PHP & Base de données Discussion :

Requête SQL avec un temps d'exécution de 7 secondes [MySQL]


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 273
    Par défaut Requête SQL avec un temps d'exécution de 7 secondes
    Bonsoir,

    Mon explication ne correspond pas vraiment à la réalité, je vais simplifier l'explication de ce à quoi sert ce que je fais.

    Je possède une base de données avec une table unique qui contient les comptes utilisateurs de mon site.
    Je possède une autre base de données avec un table qui contient plus de 2 500 000 enregistrements.

    En faite chaque utilisateur peut obtenir 1000 choses différentes, et donc dans une table j'ai mis une colonne avec le nom d'utilisateur, une autre avec le numéro de la chose obtenue, une dernière colonne avec un enum avec OUI ou NON en fonction de si la chose a été obtenue.

    Cela permet donc via un SELECT avec pour seul paramètre le nom d'utilisateur, tout ce que cet utilisateur a obtenu, ou pas obtenu.

    Le problème est que la requête UPDATE pour mettre à jour la dernière colonne, celle qui indique si la chose a été obtenue ou non, a un temps d'exécution de 6 à 7 secondes. C'est beaucoup trop pour mettre à jour des centaines d'enregistrements via une tâche cron.

    Quand je fais un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EXPLAIN UPDATE SuccesItemObtenu SET DejaObtenu = 'OUI' WHERE PlayerID = "Shart" AND IdObjet= 327;
    je constate que ça parcours plus de 1 500 000 lignes avant d'arriver à trouver l'enregistrement correspondant, et j'imagine que c'est ce qui explique la lenteur.

    Et pourtant je suis sur un serveur dédié.

    Du coup j'aimerais savoir s'il y a une solution pour accélérer l'UPDATE de façon à ce que la tâche cron ne se prenne pas systématiquement un timeout alors que moins de 2% des requêtes ont été effectuées.

    Merci d'avance

  2. #2
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 251
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 251
    Par défaut
    Je ne connais rien en MySql, mais bon, ça fonctionne pareil sur tous les sgbds.

    J'imagine que IdObjet est une clé primaire, il doit donc y avoir, surement automatiquement, un index dessus.

    Par contre quand est-il de PlayerId, as-tu un index de créé sur cette colonne ?

  3. #3
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 273
    Par défaut
    Bonsoir,

    Il n'y a aucune clé primaire. D'ailleurs une clé primaire est unique, non ? IdObjet est présent autant de fois qu'il y a de PlayerID différents, et PlayerID est présent autant de fois qu'il y a d'IdObjet différents. Par contre le même couple PlayerID et IdObjet n'est présent qu'une seule fois.

    Par hasard j'ai regroupé des conditions WHERE dans la même requête UPDATE avec un truc du genre (PlayerID = "iopp" AND IdObjet = 456) OR (PlayerID = "nbc" AND IdObjet = 145) et avec seulement 200 'OR' la quête a nécessité 3 minutes et 48 secondes pour s'exécuter ... du coup c'est impensable d'en faire le double voir plus encore si le nombre d'utilisateurs augmente.

    Edit:
    Alors là je viens de faire quelque chose que je ne comprend pas ...
    Via SQLYog je suis allé dans la partie qui permet d'éditer une table, et j'ai mis un index sur les colonnes PlayerID et IdObjet en indiquant "UNIQUE" dans le type d'index. Et là les 490 UPDATE prennent 0.268 secondes. Je ne comprend plus rien ... Est-ce bien cela qu'il fallait faire ? Et pourquoi d'un coup est-ce aussi rapide ?

  4. #4
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 251
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 251
    Par défaut
    Oui c'est cela qu'il fallait faire, le miracle de l'index

  5. #5
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 273
    Par défaut
    Je croyais que vous me demandez de mettre une clé primaire et du coup j'avais du mal à imaginer la chose car aucune valeur n'est unique mais seulement la combinaison de 2 colonnes.

    Enfin bon tant que j'ai la solution à ce problème c'est parfait, je l'utiliserais à chaque table volumineuse

    Merci beaucoup.

  6. #6
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 251
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 251
    Par défaut
    Au besoin, la clé primaire pourrait très bien être la combinaison des 2 colonnes. On appelle ça une clé composée

    Enfin, j'imagine que aussi possible sur MySql

  7. #7
    Membre Expert
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Par défaut
    Citation Envoyé par encoremoi21258 Voir le message
    Bonsoir,
    ...
    Alors là je viens de faire quelque chose que je ne comprend pas ...
    Via SQLYog je suis allé dans la partie qui permet d'éditer une table, et j'ai mis un index sur les colonnes PlayerID et IdObjet en indiquant "UNIQUE" dans le type d'index. Et là les 490 UPDATE prennent 0.268 secondes. Je ne comprend plus rien ... Est-ce bien cela qu'il fallait faire ? Et pourquoi d'un coup est-ce aussi rapide ?
    C'est le rôle des index. Imaginons que tu fasses une requête pour chercher toutes les enregistrements de l'utilisateur n° 1000.

    Si tu n'as pas d'index (et à fortiori pas de clé) le SGBD doit parcourir les 2.500.000 enregistrements pour être sûr d'avoir tout lu. Si tu as un index sur le n° d'utilisateur, le SGBD va seulement lire les enregistrements qui correspondent à 1000. Donc si tu as 100 enregistrements pour cet utilisateur tu économises 2.499.900 lecture. C'est donc beaucoup plus rapide.

  8. #8
    Membre Expert
    Avatar de Dendrite
    Femme Profil pro
    Développeuse informatique
    Inscrit en
    Juin 2008
    Messages
    2 129
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 59
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeuse informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2008
    Messages : 2 129
    Billets dans le blog
    8
    Par défaut
    Sinon, si ça n'est pas une base trop sensible tu pourrais nous mettre le sql de la structure de toutes tes tables (sans les données biens sûr !) ?
    Tu as peut etre encore beaucoup d'améliorations à faire...
    PDO, une soupe et au lit !
    Partir de la fin est un bon moyen de retrouver son chemin. Bibi - 2020

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Exécuter une requête SQL avec Hibernate Interceptor
    Par top007 dans le forum Hibernate
    Réponses: 0
    Dernier message: 13/08/2014, 11h47
  2. Problème exécution requête SQL avec HSQLDB
    Par montis dans le forum JDBC
    Réponses: 1
    Dernier message: 23/03/2012, 09h37
  3. Exécuter des requête SQL (avec ou sans PHP) dans javascript
    Par mir540 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 20/11/2009, 10h03
  4. Réponses: 1
    Dernier message: 27/03/2009, 19h04
  5. PB requète SQL avec Interbase
    Par missllyss dans le forum InterBase
    Réponses: 2
    Dernier message: 15/07/2003, 11h37

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