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 :

Base de données lourdes [MySQL]


Sujet :

PHP & Base de données

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 24
    Points : 17
    Points
    17
    Par défaut Base de données lourdes
    Bonjour;
    Je travaille actuellement sur une base de donnés assez importante 3 tables chacune d 'entre elle contient au minimum 40000 enregistrement:

    Voici sa structure:
    [IMG] http://www.imgplace.com/viewimg810/584/37sansre.png [/IMG]

    Ma requete :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    SELECT `civilite`, `name`,`prenom`, `score`,`telephone` FROM  `users` 
     
    Left Join users_Adresse_link ON users.UserID=users_Adresse_link.UserID 
    Left Join Adresse ON Adresse.AdresseID=users_Adresse_link.AdresseID
     
     
     
    Left Join  users_telephone_link ON users.UserID= users_telephone_link.UserID 
    Left Join   telephone ON   telephone.telephoneID= users_telephone_link.telephoneID
     
     
     
    WHERE users.UserID IN (select last_insert_id(UserID) from users) AND telephone.telephone IN (select telephone FROM telephone where telephone like '%$search%') ORDER BY users.USERID DESC LIMIT 1 ;

    Mon probléme est que cette requete met un temps important a m'afficher le resultat

    Merci pour votre aide

  2. #2
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    Je vois aucune relation entre tes tables sur ton schema c'est normal ?
    Ce qui induit la question suivante :

    As tu correctement indéxé les champs qui doivent l'être notamment les clés étrangère ?

    -- edit --

    C'est quoi le but de cette horreur ^^ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    users.UserID IN (select last_insert_id(UserID) from users)
    Précise nous ce que tu cherche à retirer de ta bdd exactement , on doit sans doute pouvoir simplifier la requête
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 24
    Points : 17
    Points
    17
    Par défaut Base de données lourdes
    Citation Envoyé par grunk Voir le message
    Je vois aucune relation entre tes tables sur ton schema c'est normal ?
    Ce qui induit la question suivante :

    As tu correctement indéxé les champs qui doivent l'être notamment les clés étrangère ?

    -- edit --

    C'est quoi le but de cette horreur ^^ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    users.UserID IN (select last_insert_id(UserID) from users)
    Précise nous ce que tu cherche à retirer de ta bdd exactement , on doit sans doute pouvoir simplifier la requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    users.UserID IN (select last_insert_id(UserID) from users)
    je cherche à afficher le dernier user ayant été enrgistré .

    Oui mes champs sont indexés, j'ai testé ma requete sur 30 enregistrements et elle fonctionne parfaitement, à 5000 enregistrements sa plante.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    c'est en effet une requête complexe, avec join et sous-requetes.

    Peut-être aurais-tu intérêt à commencer par :
    1/ envoyer "un éclaireur" pour trouver l'id :
    -> executer : "select last_insert_id(UserID) AS Id_last from users;"
    => $Id_last = $result['Id_last'];
    2/ envoyer "l'infanterie" pour vérifier si le telephone est bien dans la table :
    -> executer : "select telephone FROM telephone where telephone like '%$search%'"
    => $tel_search = $result['telephone'];
    3/ ne lancer "la grosse artillerie" QUE si on trouve un résultat pour $Id_last et $tel_search.
    la fin de la requête étant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE users.UserID = '".$Id_last."' AND telephone.telephone = '".$tel_search."' ORDER BY users.USERID DESC LIMIT 1 ;
    Je pense que les 2 1eres requetes donneront rapidement un résultat.
    Quant à la 3ème ... elle saura tout de suite où chercher.
    Dernière modification par Invité ; 03/08/2011 à 12h18.

  5. #5
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    je cherche à afficher le dernier user ayant été enrgistré
    Donc à mon avis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    users.UserID IN (select last_insert_id(UserID) from users)
    ne sert à rien puisque
    ORDER BY users.USERID DESC LIMIT 1
    le fait déjà et beaucoup plus vite.

    La sous requete du téléphone ne me semble pas contournable.

    Comme le dit jreaux62 , il peut être très avantageux de découper les traitements.

    Note au passage que 40k ligne dans une table c'est vraiment pas grand chose , donc y'a effectivement un problème quelque part
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 24
    Points : 17
    Points
    17
    Par défaut base de données lourde
    Citation Envoyé par jreaux62 Voir le message
    Bonjour,
    c'est en effet une requête complexe, avec join et sous-requetes.

    Peut-être aurais-tu intérêt à commencer par :
    1/ envoyer "un éclaireur" pour trouver l'id :
    -> executer : "select last_insert_id(UserID) AS Id_last from users;"
    => $Id_last = $result['Id_last'];
    2/ envoyer "l'infanterie" pour vérifier si le telephone est bien dans la table :
    -> executer : "select telephone FROM telephone where telephone like '%$search%'"
    => $tel_search = $result['telephone'];
    3/ ne lancer "la grosse artillerie" QUE si on trouve un résultat pour $Id_last et $tel_search.
    la fin de la requête étant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE users.UserID = '".$Id_last."' AND telephone.telephone = '".$tel_search."' ORDER BY users.USERID DESC LIMIT 1 ;
    Je pense que les 2 1eres requetes donneront rapidement un résultat.
    Quant à la 3ème ... elle saura tout de suite où chercher.
    logique!

    une derniere question , c est faisable avec une recherche instantané?
    l'utilisateur pourra simplement tapper le numero de telephone et lui afficher le resultat?

    si je ne procéde pas ainsi changer de serveur plus performant resoudra t il mon probleme?

    Merci

  7. #7
    Invité
    Invité(e)
    Par défaut
    Si c'est un utilisateur enregistré, il doit avoir un UserID.
    Que tu peux enregistrer dans une session (par exemple)
    Ensuite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ... WHERE users.UserID = '".$_SESSION['UserID']."' ...
    Si c'est une recherche uniquement sur le num de tél :
    -> executer juste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "select telephone FROM telephone where telephone like '%$search%'"

  8. #8
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 24
    Points : 17
    Points
    17
    Par défaut base de données lourde
    J'ai modifié la requete en ajoutant les alias,en effectuant des index sur la base et en changeant de serveur aussi resultat => 1m36 a 13 sec le temps de l'affichage du resultat.pas loin du 0 , je pense me concentrer sur les index , avez vous une idée ou les placer exactement ?
    Merci

  9. #9
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    petite question : à quoi sert la recherche sur le "telephone" ?
    est-elle utile ?
    plus précisément : pourquoi faire la recherche d'équivalence dans la BdD alors qu'on peut faire la vérification après, en php.
    bon, je me rends compte que ce n'est pas plus clair ...

    1/ -> executer : "select last_insert_id(UserID) AS Id_last from users;"
    => $Id_last = $result['Id_last'];

    2/ -> executer : "select telephone FROM telephone where telephone like '%$search%'"
    => $tel_search = $result['telephone'];


    3/ la "grosse" requete :
    SELECT `civilite`, `name`,`prenom`, `score`,`telephone` FROM `users`
    Left Join users_Adresse_link ON users.UserID=users_Adresse_link.UserID
    Left Join Adresse ON Adresse.AdresseID=users_Adresse_link.AdresseID
    Left Join users_telephone_link ON users.UserID= users_telephone_link.UserID
    Left Join telephone ON telephone.telephoneID= users_telephone_link.telephoneID
    WHERE users.UserID = '".$Id_last."' AND telephone.telephone = '%".$tel_search."%' ORDER BY users.USERID DESC LIMIT 1 ;

    4/ on récupère donc le telephone de CET utilisateur !
    $tel_user_from_bd = ...;

    $search -> c'est le tel à vérifier
    5/ on a juste à comparer $tel_user_from_bd et $search (en php) :
    if(strpos ( $tel_user_from_bd , $search )) {
    ...
    Car c'est surtout cette partie de la requête qui prends prenait un temps fou :
    ... AND telephone.telephone = '%".$tel_search."%' ...
    Dernière modification par Invité ; 05/08/2011 à 15h31.

  10. #10
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    me concentrer sur les index , avez vous une idée ou les placer exactement ?
    En règle générale on place les index sur les clés ( automatique pour les clé primaire).
    On peut également en placer sur les champs qui vont être beaucoup utiliser dans les clauses WHERE.

    Attention tout de même, trop d'index peut tuer l'index
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 24
    Points : 17
    Points
    17
    Par défaut base de données lourde
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE users.UserID IN (select last_insert_id(UserID) from users) AND telephone.telephone IN (select telephone FROM telephone where telephone like '%$search%') ORDER BY users.USERID DESC LIMIT 1 ;
    users.UserID IN (select last_insert_id(UserID) from users)=> recherche le dernier users inscrit suivant l'id


    ORDER BY users.USERID DESC LIMIT 1 ;=> recherche le dernier users inscrit suivant l'id

    2 conditions qui aboutissent au meme resultat donc double travail , j'ai juste supprimer
    "users.UserID IN (select last_insert_id(UserID) from users)"

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

Discussions similaires

  1. [AC-2003] Base de données très lourde: optimisation des échanges réseaux
    Par thomas.m dans le forum Modélisation
    Réponses: 7
    Dernier message: 22/07/2011, 17h31
  2. base de données lourde
    Par jeyweb2 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 28/11/2010, 02h03
  3. base de donnée lourde
    Par jeyweb2 dans le forum MySQL
    Réponses: 1
    Dernier message: 18/11/2010, 14h46
  4. base de données lourde
    Par da_latifa dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 10/07/2007, 10h21

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