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 :

Optimisation Php Mysql [MySQL]


Sujet :

PHP & Base de données

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 27
    Points : 18
    Points
    18
    Par défaut [Résolu]Optimisation Php Mysql
    Bonjour,

    J'ai un soucis avec un de mes sites

    Sur ce site, une page avec une dizaine de requêtes mysql est lancée en moyenne 1800 fois par minute tout le long de la journée

    dans cette page il y a trois types de requêtes

    Des SELECT avec WHERE et LIMIT 1 si je veux récupérer un seul enregistrement
    DES UPDATE d'un seul enregistrement
    et des INSERT INTO

    Pour les SELECT je prends une ligne au hasard parmi plus de 20 000 enregistrements
    J'utilise pour ça un SELECT champ1,champ2 FROM table ORDER BY Rand() LIMIT 1

    Il se trouve que le serveur monte en ce moment à 20 de charge
    et que j'essaye de tout optimiser mais je ne trouve plus de solutions

    Merci si quelqu'un peut m'aider

  2. #2
    Membre expérimenté

    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    1 138
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 138
    Points : 1 504
    Points
    1 504
    Par défaut
    Déjà le rand ça consomme toujours, car meme si tu sélectionnes une seule ligne, il va la sélectionner parmi 20.000 lignes.

    De plus, sur des grosses tables, si tu fais des grosses jointures, ou pire, que tu fais des inclusions (genre select ... where id IN (select...)) , ça va exploser.

    Il se peut aussi que le serveur ne soit pas fait pour ce genre de bases (je connais beaucoup de mutu qui accepte moyen les select sur plus de 10.000 enregistrements...).

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 62
    Points : 84
    Points
    84
    Par défaut Optimisation
    Je suis d'accord avec l'auteur du post précédent concernant l'utilisation du RAND(). Peut être, pour soulager le serveur MySQL, il vaut mieux remplacer la fonction rand() de MYSQL par un nombre générè par la fonction rand() de PHP. Ces requétes seront stockées dans le cache du MYSQL. La réponse sera plus rapide.

    En suite, créer des index sur des champs utilisés dans WHERE .

    Et pour finir, utiliser INSERT DELAYED et UPDATE LOW_PRIORITY .

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 27
    Points : 18
    Points
    18
    Par défaut
    Merci beaucoup de votre aide

    Pour raideman
    Ce n'est malheuresement pas un mutualisé, c'est déjà un coreduo 1.8 avec 2 go de ram et je vais à la perte si je dois changer tous les 6 mois

    Le problème n'est pas le fait de faire un select sur 20 000 enregistrements mais que la page qui fait des select et autres et affichée environ 1800 fois par minute d'où le problème

    Dans le code il n'y a aucun jointure ou de in juste des requetes toutes simples et des select avec un order by rand() et une limite 1

    Pour kodeya,
    Pourrais tu me donner un exemple de requete en utilisant la fonction rand de php stp

    merci

  5. #5
    Membre éprouvé Avatar de fenkys
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 376
    Points : 1 054
    Points
    1 054
    Par défaut
    J'ai un doute sur le résultat de la requête :
    SELECT champ1,champ2 FROM table ORDER BY Rand() LIMIT 1

    MySQL dit sur son site
    Vous ne pouvez pas utiliser une colonne de valeur RAND() dans une clause ORDER BY, parce que ORDER BY va évaluer la colonne plusieurs fois. Dans la version 3.23 de MySQL, vous pouvez, tout de même, faire ceci :

    mysql> SELECT * FROM tbl_name ORDER BY RAND();
    Cette syntaxe est très pratique pour faire une sélection aléatoire de lignes
    Donc à moins d'avoir MySQL 3.23 ta requête est fausse. De toute façon, une requête qui ne marche que sur un système particulier dans un cas particulier est à éviter.

    Pour ta réponse :
    Dans cet exemple, $maxLine représente le nombre de lignes de ta table, que tu auras determiné autrement (par un précedent select par exemple).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $rank = rand(1,$maxLine);
    $query = "SELECT champ1,champ2 FROM table ORDER BY ta_colonne_de_classement LIMIT $rank,1";

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 27
    Points : 18
    Points
    18
    Par défaut
    Merci de ta réponse

    Je ne vois pas bien la différence entre ma requete et celle que tu m'indiques ?
    Il serait obligatoire de sélectionner tous les champs avec * dans le select ?

    J'ai essayé de remplacé l'order by rand() par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     $offset_result = mysql_query( " SELECT FLOOR(RAND() * COUNT(*)) AS `offset` FROM table ");
    $offset_row = mysql_fetch_object( $offset_result );
    $offset = $offset_row->offset;
    $resultat2 = mysql_query( " SELECT id FROM table WHERE ... LIMIT $offset, 1 " );
    ça a fait baissé la charge du serveur, mais le script a planté au bout d'un moment quand il n'a pas reussi à recupérer les données dans la table

    Y aurait-il une erreur dans le code ?

    La recherche aléatoire se fait sur une table dont les id ne se suivent pas. et certaines lignes sont désactivées par un booléen et d'autres supprimées donc je ne peux pas compter le nombre de lignes et faire un random en php

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 62
    Points : 84
    Points
    84
    Par défaut
    La différence entre ta requête et la requête de fenkys ce que la requête de funky 'soulage' le serveur MYSQL car il n'a que trouver 1 enregistrement. La tienne oblige MYSQL de selectionner 20 000 enregistrements de ta table, les trier aléatoirement et en sélectionner un. Quand on multiplie ça par 1800 fois par minute c'est normal que la charge monte.

    Maintenant la requête. D'abord, count() permet de savoir le nombre de lignes. Ce qui n'as rien a voir avec des ids. Si tu supprime 10 000 et ensuite insère 10 000 tu vas toujours avoir 20 000 lignes tandis que les ids seront supérieurs à 20 000. Ta requête ne retournera rien dans ce cas. Donc, il faut récupérer le dernier ID de la table. Et pour pallier le problème des enregistrements supprimés on 'triche' en faisant quelque chose comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    // le dernier ID valide de la table
    $conditionSQL = '...' ;
    $offset_result = mysql_query( " SELECT id FROM table WHERE $conditionSQL order by id DESC limit 1 ");
    $offset_row = mysql_fetch_object( $offset_result );
    $offset = $offset_row->offset;
    $offset = $offset  - 1 ; // voir la requête plus bas
    $rank = rand( 0 , $offset  ); // id aléatoire avec PHP
    $resultat2 = mysql_query( " SELECT id FROM table WHERE id > $rank and $conditionSQL  LIMIT 1 " );
    a+

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 27
    Points : 18
    Points
    18
    Par défaut
    Merci pour cet exemple
    je teste ça ce soir en ligne et je te dirai si ça fonctionne bien et si ça fait baisser la charge du serveur

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 27
    Points : 18
    Points
    18
    Par défaut
    Un grand merci à vous tous pour votre aide

    Pour info, j'étais donc à 20 de charge cpu, j'avais modifié moi même le code et supprimé quelques milliers de comptes inactifs pour alléger la base et j'étais passé de 20 de charge cpu à 4 environ

    En suivant vos conseils et en particulier en adaptant le script fourni par kodeya ,je tourne actuellement entre 0,3 et 0,7 de charge CPU et tout fonctionne correctement

    Je n'aurai donc pas besoin de prendre un autre serveur

    Votre aide m'a été très précieuse

    Merci

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

Discussions similaires

  1. [MySQL] Optimisation de scripts PHP/MySQL
    Par DgG dans le forum PHP & Base de données
    Réponses: 368
    Dernier message: 20/11/2013, 18h59
  2. [Oracle] optimisation php mysql
    Par drclic dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 11/09/2007, 15h48
  3. [Cookies] php + mysql + fpdf optimisation
    Par bijour dans le forum Langage
    Réponses: 2
    Dernier message: 09/10/2006, 15h17
  4. [SGBD] Optimisation PHP/MySQL
    Par freesurfer dans le forum Requêtes
    Réponses: 3
    Dernier message: 13/04/2006, 13h46
  5. [MySQL] [Script]Optimisation de scripts Php/MySQL (2)
    Par copy dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 27/08/2004, 08h33

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