Query sur DB Oracle via PHP : charge CPU énorme !

Query sur DB Oracle via PHP : charge CPU énorme ! - SQL/NoSQL - Programmation

Marsh Posté le 12-06-2004 à 16:37:48    

Hello!
 
Lorsque je lance certains query sur une DB Oracle (sur Unix), via un script php (php sur un serveur distinct, et affichage en HTML direct dans le browser du client qui envoie la requête), la charge CPU sur le serveur Unix peut monter à 50% !
Le même query en SQLplus depuis un client vers le serveur ne prend jamais plus de 1,5-2%, et la vitesse d'affichage est équivalente ...
 
Comment se fait-ce ? ;)
Qu'est-ce qui, dans le traitement de la requête via php, charge autant le CPU sur Unix ?
Et est-ce paramètrable ?

Reply

Marsh Posté le 12-06-2004 à 16:37:48   

Reply

Marsh Posté le 12-06-2004 à 17:44:58    

Tu peux nous donner le soucre?

Reply

Marsh Posté le 12-06-2004 à 20:39:26    

Bah le source, je suis pas sûr que ça aidera ...
En gros c'est :

Code :
  1. <?php
  2. include("connexion.php" ); //je récupère le login/passwd à la base oracle
  3. $var = $_POST["VAR"]; //ça c'est les variables postées par le user qui s'intègrent dans le query
  4. ...
  5. ...
  6. switch - case // en fonction de ce qui est posté, une condition du query prend telle ou telle valeur
  7. $query = ("select from ..." ); //y a 3 tables jointes, dont une fait plus de 3 millions de records
  8. $parsed = ociparse($db_conn, $query);
  9. ociexecute($parsed);
  10. $nrows = ocifetchstatement($parsed, $result);
  11. echo "<html>..."; // je construis la table HTML
  12. for ($i = 0; $i < $nrows; $i++ ) // là je passe les valeurs du tableau dans la table HTML
  13. {
  14. ...
  15. }
  16. echo "</html>";
  17. ?> // Et c'est fini ... :)


Message édité par Mosca le 12-06-2004 à 20:40:52
Reply

Marsh Posté le 13-06-2004 à 15:20:56    

une jointure sur une table avec 3 millions d'enregistrements... tu l'as ecrite comment ???

Reply

Marsh Posté le 13-06-2004 à 19:26:39    

La jointure ou la table ?
La jointure est normale et reprend l'index ...
La table, c'est une table d'historique ... Ca n'arrête pas de croître au fur et à mesure des transactions ...
(C'est Oracle+un ERP, la table suit le modèle de l'ERP)

Reply

Marsh Posté le 13-06-2004 à 21:38:00    

Est-ce que tu utilises des connexions permanentes : ociplogon() ou pas : ocilogon() ?
Il faut savoir qu'ouvrir une connexion sur oracle prends un temps fou.
 
D'autre part tu compare SQLplus et PHP, avec la même requête je suppose. Mais si la version PHP fait monter la charge CPU à 50% et SQLPlus à 2%, les durées de ses charges sont-elle comparables ?

Reply

Marsh Posté le 13-06-2004 à 23:32:12    

Non, pas permanente, ocilogon uniquement ...
Oui, le même query php et sqlplus (sa structure) ...
La durée de charge ? Hum, diffcile à dire, il faudra je je teste avec précision ... A vue de nez, le temps de charge est assez comparable : si php va plus vite de 2-5 sec, ça ne justifie pas la charge cpu je pense ...

Reply

Marsh Posté le 14-06-2004 à 09:07:44    

Essayes avec ociplogon().
Avec SQLplus, tu ne comptes pas le temps et la charge CPU liée à l'ouverture d'une connexion, qui je te garantie n'est pas négigeable.
Ensuite compare des choses comparables : Charge ET Temps
Avec ociplogon, je prédis (sauf pour la première connexion) une charge en baisse ET un temps en baisse pour PHP :D
 
Après, si tu veux rester avec ocilogon, tu fais comme tu veux, mais tu sais pourquoi to truc est lent en PHP !
 
Si tu veux gérer un pool de connexions et que tu fais juste des requêtes simples, regarde du coté de SQLRelay : http://sqlrelay.sourceforge.net/
Je parles de requêtes simples parce-que j'ai voulu l'utiliser, mais nos requêtes faisaient souvent appel à des procédures stockées avec des tableaux en paramètres, et SQLRelay ne supporte pas les tableaux...


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 16-06-2004 à 18:04:32    

C'est surtout en fait que le système de connection standard de PHP ouvre et ferme une connection a chaque execution (comme le dit Mara's dad) et que du coup, Oracle ne garde pas en cache le plan d'éxécution de la requête. Et la compilation d'une requête peut d'avérer très gourmand.
 
Depuis SQL Plus, on voit très bien la chose : lance une requête ultra complexe. Ca prends mettons 5 secondes, avec une charge élevée sur le serveur pendant une seconde.
 
Sans fermer SQL Plus, modifie les valeurs des filtres de la requête (sans changer les critères par contre !) et pouf ! La ca tombe a 1 seconde, avec une charge minimale sur le serveur : il s'est contenté de lire les données en suivant les indexes, ce qui est ridicule pour Oracle même s'il y a des millions de lignes à lire.
 
Le système que préconise Mara's dad est effectivement une bonne solution, puisque l'utilisation d'un pool de connections passant par une connection unique et persistante permet a Oracle de conserver en cache ces plans d'execution.
 
Par contre, pour ce qui est de l'ouverture de la connection elle-même, je suis pas convaincu ;)


Message édité par Arjuna le 16-06-2004 à 18:05:59
Reply

Sujets relatifs:

Leave a Replay

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