Zend_Db_Profiler
peut être activé pour permettre le profilage
de requêtes. Les profils incluent les requête exécutées par l'adapteur, ainsi
que leur temps d'exécution, permettant l'inspection des requêtes qui ont été
exécutées sans avoir besoin de rajouter du code spécifique au débuggage aux classes.
L'utilisation avancé permet aussi au developpeur de filtrer quelles requêtes il
souhaite profiler.
Le profileur s'active soir en passant une directive au constructeur de l'adapteur, soit en spécifiant à l'adapteur de l'activer plus tard.
<?php require_once 'Zend/Db.php'; $params = array ( 'host' => '127.0.0.1', 'username' => 'malory', 'password' => '******', 'dbname' => 'camelot', 'profiler' => true // turn on profiler; set to false to disable (default) ); $db = Zend_Db::factory('PDO_MYSQL', $params); // coupe le profileur: $db->getProfiler()->setEnabled(false); // active le profileur: $db->getProfiler()->setEnabled(true); ?>
Vous pouvez récupérer le profileur en utilisant la méthode
getProfiler()
de l'adapteur:
<?php $profileur = $db->getProfiler(); ?>
Ceci retourne une instance de Zend_Db_Profiler
.
Avec cette instance, le développeur peut examiner les requêtes
en utilisant un éventail de méthodes :
getTotalNumQueries()
retourne le nombre total de
requêtes profilées.
getTotalElapsedSeconds()
retourne le nombre totale
de secondes écoulées pour chaque requête profilée.
getQueryProfiles()
retourne un tableau de tous les
profils de requêtes.
getLastQueryProfile()
retourne le plus récent profil
de requête, peut importe si la requête à fini de s'exécuter ou pas
(si l'exécution n'est pas finie, le temps de fin sera null).
clear()
nettoie tous les anciens profils de la pile.
La valeur de retour de getLastQueryProfile()
et
les élements individuels de getQueryProfiles()
sont
des objets de type Zend_Db_Profiler_Query
qui permettent
d'inspecter les requêtes:
getQuery()
retourne le SQL de la requête
sous forme de texte.
getElapsedSecs()
retourn le nombre de seconde
d'exécution de la requête.
L'information que Zend_Db_Profiler
founie est utile pour profiler
des goulets d'étranglement dans les applications, ainsi que pour débugger les
requêtes qui viennent d'être exécutées. Pour le moment, pour voir la dernière
requête qui vient de s'exécuter:
<?php $query = $profileur->getLastQueryProfile(); echo $query->getQuery(); ?>
Si une page se génère lentement, utilisez le profileur pour déterminer le nombre total de requêtes, et ensuite passer d'une requête à l'autre pour voir laquelle a été la plus longue:
<?php $tempsTotal = $profileur->gettotalElapsedSeconds(); $nombreRequetes = $profileur->getTotalNumQueries(); $tempsLePlusLong = 0; $requeteLaPlusLongue = null; foreach ($profileur->getQueryProfiles() as $query) { if ($query->getElapsedSecs() > $tempsLePlusLong) { $tempsLePlusLong = $query->getElapsedSecs(); $requeteLaPlusLongue = $query->getQuery(); } } echo 'Executé ' . $nombreRequetes . ' requêtes en ' . $tempsTotal . ' secondes' . "\n"; echo 'Temps moyen : ' . $nombreRequetes / $tempsTotal . ' secondes' . "\n"; echo 'Requête la plus lente : ' . $tempsLePlusLong . "\n"; echo "Requête la plus longue : \n" . $requeteLaPlusLongue . "\n"; ?>
En plus de l'inspection de requête, le profileur permet aussi
au développeur de filtrer quelles requêtes il veut profiler.
Les méthodes suivantes fonctionnent avec une instance de
Zend_Db_Profiler
:
setFilterElapsedSecs()
permet au développeur
de définir un temps minimum d'exécution de la requête avant
que celle-ci soit profilée. Pour retirer le filtre, passez
une valeur null à la méthode.
<?php // Seules les requêtes qui durent au moins 5 secondes sont profilées: $profileur->setFilterElapsedSecs(5); // Profil de toutes les requête, peu importe leur longueur: $profileur->setFilterElapsedSecs(null); ?>
setFilterQueryType()
permet au développeur de définir
quel type de requêtes doivent être profilées; to profile multiple
types, logical OR them. Les types de requêtes sont définis sous
forme de constantes de Zend_Db_Profiler
:
Zend_Db_Profiler::CONNECT
: opérations de connexion ou
de sélection de base de données.
Zend_Db_Profiler::QUERY
: requête générale qui ne
correspond pas aux autres types.
Zend_Db_Profiler::INSERT
: toute requête qui ajoute
des données dans la base de données, généralement INSERT.
Zend_Db_Profiler::UPDATE
: toute requête qui met à jour
des données, généralement UPDATE.
Zend_Db_Profiler::DELETE
: toute requête qui efface des
données, généralement DELETE.
Zend_Db_Profiler::SELECT
: toute requête qui récupère
des données, généralement SELECT.
Zend_Db_Profiler::TRANSACTION
: toute requête qui concerne
des opérations de transaction, comme start transaction, commit,
ou rollback.
Comme avec setFilterElapsedSecs()
, vous pouvez retirer
tous les filtres en passant null
comme unique argument.
<?php // profile uniquement les requêtes SELECT $profileur->setFilterQueryType(Zend_Db_Profiler::SELECT); // profile les requêtes SELECT, INSERT, et UPDATE $profileur->setFilterQueryType(Zend_Db_Profiler::SELECT | Zend_Db_Profiler::INSERT | Zend_Db_Profiler::UPDATE); // profile les requêtes DELETE $profileur->setFilterQueryType(Zend_Db_Profiler::DELETE); // Efface tous les filtres $profileur->setFilterQueryType(null); ?>
Utiliser setFilterQueryType()
peut réduire les profils
générés. Cependant il est parfois utile de garder tous les profils
et voit uniquement ceux dont on a besoin, à un moment donné.
Une autre possibilité de getQueryProfiles()
est qu'il
est possible de filtrer à la volée, en passant un type de requête
(ou une combinaison logique de types de requête) comme premier
argument; voir Section 3.2.3.2, « Filtrer par type de requête »
pour une liste des constantes de types de requête.
<?php // Récupère uniquement les profils des requêtes SELECT $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT); // Récupère uniquement les profils des requêtes SELECT, INSERT, et UPDATE $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT | Zend_Db_Profiler::INSERT | Zend_Db_Profiler::UPDATE); // Récupère uniquement les profils des requêtes DELETE (on peut donc comprendre pourquoi les données // disparaissent) $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::DELETE); ?>