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 PHP Discussion :

Réduire le nombre de requetes


Sujet :

Langage PHP

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

    Informations forums :
    Inscription : Août 2007
    Messages : 26
    Points : 22
    Points
    22
    Par défaut Réduire le nombre de requetes
    Bonjour,

    J'ai développé une petite application de gestion des interventions en php5/mysql et je rencontre un problème avec la montée en charge de cette application.

    Une intervention peut avoir une ou plusieurs actions.
    Une action peut avoir un ou plusieurs technicien.
    Un technicien appartient à un site d'une société.
    Un site appartient à une société.

    Concrètement, j'ai une classe pour chacun de ces 5 objets et dans ma base une table pour chaque objet. J'initialise un objet en lui passant un identifiant (la clé primaire), le constructeur fait un select avec l'id en paramètre et initialise les attributs de mon objet avec les résultats de la requête.

    C'est super pratique car si je veux le nom de la société du site a du technicien b de l'action c de l'intervention d, ça donne:
    $intervention[d]->action[c]->technicien[b]->site[a]->societe->nom

    Mais voilà, lorsque j'affiche 30 interventions, chacun de mes objets génère une requete à l'initialisation. Du coup, j'arrive très vite à atteindre entre 1000 et 2000 requêtes pour l'affichage d'une page (30 interventions, 2 ou 3 actions chacune, 2 ou 3 techniciens chacune, ...) !!!

    Existe-t-il des méthodes de développement (voire un framework) où, lorsqu'un objet est déjà initialisé, php rappelle l'objet instancié sans refaire la requête ?

    Je n'ai qu'une trentaine de techniciens. Si le même technicien intervient sur plusieurs actions différentes, je fais ma requête pour chacune des actions où il intervient (c'est mal). Ce que j'aimerais, c'est faire la requête qu'une seule fois et ensuite, réutiliser l'objet ainsi obtenu autant de fois que nécessaire (c'est bien).

    D'après mes recherches, je crois que la technique que j'utilise est du lazy loading. A mon avis, je me plante quelque part pour optimiser tout ça.

    Je pensai sinon charger l'ensemble des objets au démarrage de la page mais comment savoir lesquelles j'aurai besoin ? Il est impensable de charger l'ensemble des actions par exemple (plus de 16.000 aujourd'hui après seulement 6 mois d'utilisation).

    Merci pour vos réponses.

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 448
    Points : 2 284
    Points
    2 284
    Par défaut
    lazy loading exactement.

    l'idée est de ne pas appeler des objets périphérique à l'instanciation, mais JIT, just in time, bref au moment souhaité.

    Pour cela, utilise des méthodes de get, ou les accesseurs magiques de PHP.

    Schématisons la classe intervention.
    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
    class Intervention{
     
         protected $p_id_technicien;
         protected $p_technicien;
     
         public function __construct( $id=null ){
              // faire quelque chose pour lire les propriétés de l'objet 
              // genre id, nom, id_technicien ect
              // Cependant on ne charge pas maintenant l'objet technicien
         }
     
         public function getTechnicien(){
              if( $this->p_technicien == NULL )
                   $this->p_technicien = Technicien::lireParId( $this-> p_id_technicien );
              return $this->p_technicien;
         }
    }
    Et Voilàà, l'objet technicien est lazy loader. Simple non ?

    Pour refaire exactement comme cela :
    $intervention[d]->action[c]->technicien[b]->site[a]->societe->nom

    utilises __get sur le même principe.

    Ce que j'aimerais, c'est faire la requête qu'une seule fois et ensuite, réutiliser l'objet ainsi obtenu autant de fois que nécessaire (c'est bien).
    Ca c'est encore autre chose, c'est un système de cache.
    Je laisse la main à d'autres.
    Faudra te tourner vers apc, eaccelerator ect pour utiliser de la mémoire partagée.

    a plus

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    ok pour le lazy loading.

    Mon soucis vient de là:
    Code php : 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
    class Intervention
    {
        var $id;         // Identifiant de l'intervention
        var $libDemande; // Libelle de la demande
        var $actions;    // Tableau d'actions
     
        function Intervention( $id = null )
        {
            global $db;
            if ( isset( $id ) )
            {
                $this->id = intval( $id );
     
                $table = new DB_Table( T_INTERVENTIONS );
                $champs = @mysql_fetch_object( $table->load( $this->id ) );
     
                $this->libdemande = $champs->demande;
     
                $this->actions = array( );
                $table = new DB_Table( T_ACTIONS );
                $reqActions = $table->loadSpec( "id_intervention", $this->id, "dateAction" );
                while ( $champs = @mysql_fetch_object( $reqActions ) )
                {
                    $act = new Action( $champs->id );
                    array_push( $this->actions, $act );
                }
            }
        }
    }
    A l'initialisation, je lance ma requête sur les actions pour les avoir à dispo.

    Tu me diras, c'est anodin, et je pourrais faire une fonction getActions( ) que j'appelle au moment où j'ai réellement besoin des actions.

    Oui mais voilà, ça m'oblige maintenant à revoir l'ensemble de mon code. C'est une boulette que je ne ferai plus

    Je n'avais pas pensé au système de cache. Je vais de ce pas me renseigner sur les pistes que tu viens de me donner. Merci

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 448
    Points : 2 284
    Points
    2 284
    Par défaut
    Citation Envoyé par samche Voir le message
    A l'initialisation, je lance ma requête sur les actions pour les avoir à dispo.

    Tu me diras, c'est anodin, et je pourrais faire une fonction getActions( ) que j'appelle au moment où j'ai réellement besoin des actions.

    Oui mais voilà, ça m'oblige maintenant à revoir l'ensemble de mon code. C'est une boulette que je ne ferai plus
    Hey des erreurs on en fait tous, même les forgerons..
    Et à cela je ne peux rien y faire, à part te signifier que 5 - 6 classes avec peut être 20 - 25 accesseurs, ça ne me parait pas être le bout du monde.
    Mais cela ne concerne que moi.

    Pour le système de cache http://www.php.net/apc

    bye

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    495
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 495
    Points : 396
    Points
    396
    Par défaut
    je crois que propel gere le lazy loading :
    http://propel.phpdb.org/trac/

Discussions similaires

  1. [MySQL-5.6] Réduire le nombre de requetes à la base
    Par laurent1 dans le forum Requêtes
    Réponses: 4
    Dernier message: 29/06/2015, 15h38
  2. Réponses: 8
    Dernier message: 17/02/2014, 16h21
  3. [securite] limiter le nombre de requete htaccess
    Par jojo33bx dans le forum Langage
    Réponses: 1
    Dernier message: 27/02/2007, 20h18
  4. Nombre de requetes simultanées MSDE
    Par BigLebowski dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 16/01/2007, 13h56
  5. [MySQL] Nombre de requetes exécutées dans une page
    Par AlphonseBrown dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 30/11/2005, 19h38

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