performance active record [php] - PHP - Programmation
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...
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.
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)
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?
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.
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...
speedyop a écrit : sur la meme machine si ca strouve y'aurait pas ce pb. |
Je vois pas pourquoi.
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)
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.
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.
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...
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.
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
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.
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
Marsh Posté le 20-04-2008 à 14:38:42
speedyop 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?
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...
Ton findByClass1_id pourrait retourner directement un tableau de Class2..
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...
Marsh Posté le 20-04-2008 à 17:52:24
skeye a écrit : |
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...
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!
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...
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...
Marsh Posté le 22-04-2008 à 21:46:42
Ya des trucs comme KCacheGrind, vmstat ...
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...
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?