[php] performance active record

performance active record [php] - PHP - Programmation

Marsh Posté le 19-04-2008 à 17:42:03    

Que pensez-vous des performances d'un modèle active record en php ?
 
après avoir mappé chacune des tables a un objet dérivé d'une classe mère de type CRUD (Create, Read, Update, Delete), j'ai créé les relation entre les tables du type  
 
class1 possède des class2
class2 possède des class3
etc
 
au début je "mountait" les classes dépendantes automatiquement a l'instantiation ça me donnait directement les classes filles
 
genre  
 
$class1->class2[0]->class3[2]
 
le nombre de requette simple attaquant une seule table peut de cette facon très vite monter.
 
1erement j'ai désactivé l'automount et mount a la main selon le besoin.
2ement j'overload certaines methodes pour faire une requettes avec jointure recuperant toutes les données necessaire pour remplir mes objet.
 
Mais au final j'y perds de la simplicité du model active record, étant obligé pour des questions de performance d'overloader pas mal de truc au cas par cas. Pensant ne plus avoir a penser au SQL, je fini par ecrire chaque requette :/
 
des avis?

Reply

Marsh Posté le 19-04-2008 à 17:42:03   

Reply

Marsh Posté le 19-04-2008 à 18:06:54    

si tu veux des perfs sur des requêtes complexes, il faudra écrire les requêtes à la main quelle que soit la méthode utilisée...


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 20-04-2008 à 00:04:20    

Skeye a raison.
 
C'est con à dire, mais on ne pourra jamais demander à une classe de réaliser automatiquement ce que tu souhaites faire pour un besoin précis.


Message édité par CyberDenix le 20-04-2008 à 11:04:15

---------------
Directeur Technique (CTO)
Reply

Marsh Posté le 20-04-2008 à 10:52:59    

en fait ca je le savait, je voulais avoir l'application entiere fonctionelle rapidement grace au design pattern generique, puis ensuite refactorer et optimiser. la je peut pas car je met a genoux le pov serveur (php4.05 et seulement 512mo de ram)

Reply

Marsh Posté le 20-04-2008 à 11:21:04    

speedyop a écrit :

en fait ca je le savait, je voulais avoir l'application entiere fonctionelle rapidement grace au design pattern generique, puis ensuite refactorer et optimiser. la je peut pas car je met a genoux le pov serveur (php4.05 et seulement 512mo de ram)


euh 512 mo de ram c'est déjà beaucoup pour du php...sauf si la base est sur le même serveur? :??:


Message édité par skeye le 20-04-2008 à 11:21:17

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 20-04-2008 à 11:30:14    

non la base sybase est séparée et a 8go. Le probleme est bizarre : le nombre de requette important sur une courte durée consomme la mémoire de façon abusé, c'est justement que chaque requette est un echange entre la machine BDD et la machine apache. Apache monte rapidement a 400mo et + et apres bonjour le swapa disque dur. sur la meme machine si ca strouve y'aurait pas ce pb.

Reply

Marsh Posté le 20-04-2008 à 11:47:01    

speedyop a écrit :

non la base sybase est séparée et a 8go. Le probleme est bizarre : le nombre de requette important sur une courte durée consomme la mémoire de façon abusé, c'est justement que chaque requette est un echange entre la machine BDD et la machine apache. Apache monte rapidement a 400mo et + et apres bonjour le swapa disque dur..


400mo en dev avec un seul utilisateur? Il y a un soucis avec ton implé d'active record, pas possible autrement...c'est censé consommer beaucoup mais faut pas exagérer là quand même...[:pingouino]

 


speedyop a écrit :

sur la meme machine si ca strouve y'aurait pas ce pb.

 

Je vois pas pourquoi.


Message édité par skeye le 20-04-2008 à 11:47:40

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 20-04-2008 à 12:19:23    

un echange entre 2 serveur sur la meme machine devrait etre moins gourmand qu'un echange entre 2 machine distinct qui plus est relié en 10mbits (meme pas 100)

Reply

Marsh Posté le 20-04-2008 à 12:26:43    

speedyop a écrit :

un echange entre 2 serveur sur la meme machine devrait etre moins gourmand qu'un echange entre 2 machine distinct qui plus est relié en 10mbits (meme pas 100)


Ta machine avec 512 mo de ram serait à l'agonie, avec la bdd à faire tourner en plus.:D
Et ce n'est pas avec un seul utilisateur qui visualise une page web que tu vas saturer le réseau...qui n'a de toute manière rien à voir avec la mémoire.
Et la conso mémoire spécifiquement liée au dialogue entre php et la base serait exactement la même.


Message édité par skeye le 20-04-2008 à 12:28:05

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 20-04-2008 à 12:30:17    

...et pour tes problèmes de conso mémoire, ce serait une bonne idée de regarder les requêtes que tu génères (combien? est-ce qu'elles ne retournent pas bcp plus que ce dont tu as besoin?), parce-que ça me parait quand même extravagant de consommer 400mo avec une page simple...


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 20-04-2008 à 12:30:17   

Reply

Marsh Posté le 20-04-2008 à 12:40:39    

Sauf si il exécute des requétes sur une table énorme, optimiser tes requétes c'est bien mais la structure de tes tables et leur contenue est au moins aussi important.

Reply

Marsh Posté le 20-04-2008 à 12:53:52    

dans le model active record je remonte bien entendu des informations inutile $class1 est mappé sur table1 et remonte tous les champs, mais un objet = une ligne de la table.
 
en modele active record, La page a une trentaine de requette simple du style select * from table where id=$value, id etant pk.
 
J'ai fait un benchmark avec ab (apache benchmark) et je ne voit pas de consommation exessive, mais en réel ca consomme... :/
 
La base est grosse, mais je dirais en terme de BDD c'ets pas exhessif... klk millions de lignes par table.
en fait oui le probleme vient peut etre de l'administration de la bdd mais je ne peut pas rejeter la faute sur le DBA. Le code procedural qu'ils ont pondu jusqu'a lors n'a jamais mis a genoux les serveur, et j'arrive avec ma POO et mes design pattren, c'est bien beau sur le papier mais en pratique ca marche pas dans leur environmenet :/


Message édité par speedyop le 20-04-2008 à 12:56:25
Reply

Marsh Posté le 20-04-2008 à 13:06:12    

Je connais pas tes requetes mais si tu t'amuses ne serais-ce qu'a faire une boucle pour parcourir une table de "quelques" millions de lignes, ne t'étonnes pas d'avoir un script qui rame avec une conso de folie.

Reply

Marsh Posté le 20-04-2008 à 13:19:16    

c'est en effet le principe de l'implementation des "has many" que j'ai faites.
voulant imiter rails et cakephp.  
 
en faisant  
 
$class1 = new Class1($id);
 
si dans Class1 j'ai un
 
var $has(array(
    array(
        'what'       => 'Class2',
        'foreign'    => 'class1_id'
    )
));
 
je fait un static $list = Class2::findByClass1_id($id)
je boucle la liste pour instancier chaque class2
 
$nb = count($list);
foreach($x=0;$x<$nb;$x++){
    $class1->Class2[$x] = new Class2($list[$x])
}
 
donc j'en reviens a ma question de base : l'active records c'est bien sur le papier mais quand on a des machines de merde c'est pas applicable :/

Reply

Marsh Posté le 20-04-2008 à 14:38:42    

speedyop a écrit :


$nb = count($list);
foreach($x=0;$x<$nb;$x++){
    $class1->Class2[$x] = new Class2($list[$x])
}

 

Ouais donc là tu refais une requête par objet de type class2, non?
Tu peux pas essayer d'optimiser un peu le principe pour aller chercher en une seule requête tous les objets?[:pingouino]
Ca fait une putain d'usine à gaz, d'implémenter ça de manière naïve...tu m'étonnes que ça donne un truc lourd...[:dawao]

 

Ton findByClass1_id pourrait retourner directement un tableau de Class2..:o

Message cité 1 fois
Message édité par skeye le 20-04-2008 à 14:39:50

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 20-04-2008 à 14:51:46    

speedyop a écrit :

donc j'en reviens a ma question de base : l'active records c'est bien sur le papier mais quand on a des machines de merde c'est pas applicable :/


 
Ce n'est pas un problème de machine, c'est un problème d'implémentation. Ta manière de faire est ridiculeusement naïve, là.
Utiliser Active Record ne te dispense pas de réfléchir un peu à ce qui se passe derrière quand tu écris tes méthodes...


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 20-04-2008 à 17:52:24    

skeye a écrit :


 
Ouais donc là tu refais une requête par objet de type class2, non?
Tu peux pas essayer d'optimiser un peu le principe pour aller chercher en une seule requête tous les objets?[:pingouino]
Ca fait une putain d'usine à gaz, d'implémenter ça de manière naïve...tu m'étonnes que ça donne un truc lourd...[:dawao]
 
Ton findByClass1_id pourrait retourner directement un tableau de Class2..:o


 
c est ce que j'ai effectivement été obligé de faire, mais j'y perds en generique... v voir lundi si c possible de "prevoir" quelles table je dois lire, et le faire en une requette...

Reply

Marsh Posté le 20-04-2008 à 18:05:54    

speedyop a écrit :

c est ce que j'ai effectivement été obligé de faire, mais j'y perds en generique...


Pourquoi donc? Tu peux envisager que pour chaque table ayant une clé étrangère tu as une méthode statique qui retourne tous les objets ayant une valeur donnée pour cette clé, ça parait pas stupide à généraliser...bref il n'y a pas qu'un moyen de faire une chose, et le mieux est d'y réfléchir avant!:D


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 21-04-2008 à 10:37:03    

je pense avoir trouvé la veritable cause de la surcharge mémoire : toutes les variables remplies en php le restent jusqu'a la fin du script! bon bah va falloir que je place quelques unset(), c'est assez con, c vrai que j'ai jamais eu a le faire en php...

Reply

Marsh Posté le 21-04-2008 à 10:47:20    

Je reste persuadé que tu charges beaucoup trop de choses...plutôt que libérer la mémoire plus tôt personnellement j'essaierais d'en consommer moins...
Là tu soignes les symptômes au lieu d'attaquer le problème...


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 22-04-2008 à 21:46:42    

Ya des trucs comme KCacheGrind, vmstat ...


---------------
Echange de 3000+ liens PR 3 -> 5, me pm urgent !
Reply

Marsh Posté le 23-04-2008 à 11:42:33    

le premier truc serai de passer en php5 peut etre, et ca j'ai beau insister...

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed