Zend_Db_Profiler.xml 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 24249 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.db.profiler" xmlns:xi="http://www.w3.org/2001/XInclude">
  5. <title>Zend_Db_Profiler</title>
  6. <sect2 id="zend.db.profiler.introduction">
  7. <title>Introduction</title>
  8. <para>
  9. <classname>Zend_Db_Profiler</classname> peut être activé pour permettre le
  10. profilage de requête. Les profils incluent les requêtes exécutées par l'adaptateur,
  11. ainsi que leur temps d'exécution, permettant l'inspection des requêtes qui ont été
  12. exécutées sans avoir besoin de rajouter le code spécifique de débogage aux classes.
  13. L'utilisation avancée permet aussi au développeur de filtrer quelles requêtes il
  14. souhaite profiler.
  15. </para>
  16. <para>
  17. Le profileur s'active soit en passant une directive au constructeur de
  18. l'adaptateur, soit en spécifiant à l'adaptateur de l'activer plus tard.
  19. </para>
  20. <programlisting language="php"><![CDATA[
  21. $params = array(
  22. 'host' => '127.0.0.1',
  23. 'username' => 'webuser',
  24. 'password' => 'xxxxxxxx',
  25. 'dbname' => 'test',
  26. 'profiler' => true // active le profileur ;
  27. // mettre à false pour désactiver
  28. // (désactivé par défaut)
  29. );
  30. $db = Zend_Db::factory('PDO_MYSQL', $params);
  31. // stoppe le profileur :
  32. $db->getProfiler()->setEnabled(false);
  33. // active le profileur :
  34. $db->getProfiler()->setEnabled(true);
  35. ]]></programlisting>
  36. <para>
  37. La valeur de l'option <property>profiler</property> est souple. Elle est interprétée
  38. différemment suivant son type. La plupart du temps, vous devriez simplement utiliser une
  39. variable booléenne, mais d'autres valeurs vous permettent de personnaliser le
  40. comportement du profileur.
  41. </para>
  42. <para>
  43. Un argument booléen active le profileur si c'est une valeur <constant>TRUE</constant>,
  44. ou le désactive si <constant>FALSE</constant>. La classe de profileur est celle par
  45. défaut, par exemple <classname>Zend_Db_Profiler</classname>.
  46. </para>
  47. <programlisting language="php"><![CDATA[
  48. $params['profiler'] = true;
  49. $db = Zend_Db::factory('PDO_MYSQL', $params);
  50. ]]></programlisting>
  51. <para>
  52. Une instance d'un objet profileur fait que l'adaptateur utilise cet objet. L'objet
  53. doit être de type <classname>Zend_Db_Profiler</classname> ou une sous-classe.
  54. L'activation du profileur est faite séparément.
  55. </para>
  56. <programlisting language="php"><![CDATA[
  57. $profiler = Mon_Db_Profiler();
  58. $profiler->setEnabled(true);
  59. $params['profiler'] = $profiler;
  60. $db = Zend_Db::factory('PDO_MYSQL', $params);
  61. ]]></programlisting>
  62. <para>
  63. L'argument peut être un tableau associatif contenant une ou toutes les clés
  64. suivantes : "<property>enabled</property>", "<property>instance</property>", et
  65. "<property>class</property>". Les clés "<property>enabled</property>" et
  66. "<property>instance</property>" correspondent aux types booléen et instance décrites
  67. ci-dessus. La clé "<property>class</property>" est utilisée pour
  68. nommer une classe à prendre en tant que profileur personnalisé. La classe doit être de
  69. type <classname>Zend_Db_Profiler</classname> ou une sous-classe. La classe est
  70. instanciée sans aucun argument de constructeur. L'option "<property>class</property>"
  71. est ignorée quand l'option "<property>instance</property>" est fournie.
  72. </para>
  73. <programlisting
  74. language="php"><![CDATA[
  75. $params['profiler'] = array(
  76. 'enabled' => true,
  77. 'class' => 'Mon_Db_Profiler'
  78. );
  79. $db = Zend_Db::factory('PDO_MYSQL', $params);
  80. ]]></programlisting>
  81. <para>
  82. Enfin, l'argument peut être un objet de type <classname>Zend_Config</classname>
  83. contenant des propriétés, qui sont traitées comme les clés de tableaux décrites
  84. ci-dessus. Par exemple, un fichier "<filename>config.ini</filename>" peut
  85. contenir les données suivantes&#160;:
  86. </para>
  87. <programlisting language="ini"><![CDATA[
  88. [main]
  89. db.profiler.class = "Mon_Db_Profiler"
  90. db.profiler.enabled = true
  91. ]]></programlisting>
  92. <para>
  93. Cette configuration peut être appliquée par le code <acronym>PHP</acronym>
  94. suivant&#160;:
  95. </para>
  96. <programlisting language="php"><![CDATA[
  97. $config = new Zend_Config_Ini('config.ini', 'main');
  98. $params['profiler'] = $config->db->profiler;
  99. $db = Zend_Db::factory('PDO_MYSQL', $params);
  100. ]]></programlisting>
  101. <para>
  102. La propriété "<property>instance</property>" peut être utilisée comme ceci&#160;:
  103. </para>
  104. <programlisting language="php"><![CDATA[
  105. $profiler = new Mon_Db_Profiler();
  106. $profiler->setEnabled(true);
  107. $configData = array(
  108. 'instance' => $profiler
  109. );
  110. $config = new Zend_Config($configData);
  111. $params['profiler'] = $config;
  112. $db = Zend_Db::factory('PDO_MYSQL', $params);
  113. ]]></programlisting>
  114. </sect2>
  115. <sect2 id="zend.db.profiler.using">
  116. <title>Utiliser le profileur</title>
  117. <para>
  118. A n'importe quel moment, vous pouvez récupérer le profileur en utilisant la
  119. méthode <methodname>getProfiler()</methodname> de l'adaptateur&#160;:
  120. </para>
  121. <programlisting language="php"><![CDATA[
  122. $profileur = $db->getProfiler();
  123. ]]></programlisting>
  124. <para>
  125. Ceci retourne une instance de <classname>Zend_Db_Profiler</classname>. Avec cette
  126. instance, le développeur peut examiner les requêtes en utilisant un éventail de
  127. méthodes&#160;:
  128. </para>
  129. <itemizedlist>
  130. <listitem>
  131. <para>
  132. <methodname>getTotalNumQueries()</methodname> retourne le nombre total de
  133. requêtes profilées.
  134. </para>
  135. </listitem>
  136. <listitem>
  137. <para>
  138. <methodname>getTotalElapsedSecs()</methodname> retourne le nombre total de
  139. secondes écoulées pour chaque requête profilée.
  140. </para>
  141. </listitem>
  142. <listitem>
  143. <para>
  144. <methodname>getQueryProfiles()</methodname> retourne un tableau de tous les
  145. profils de requêtes.
  146. </para>
  147. </listitem>
  148. <listitem>
  149. <para>
  150. <methodname>getLastQueryProfile()</methodname> retourne le profil de requête le
  151. plus récent, peut importe si la requête à fini de s'exécuter ou pas (si
  152. l'exécution n'est pas finie, le temps de fin sera <constant>NULL</constant>).
  153. </para>
  154. </listitem>
  155. <listitem>
  156. <para>
  157. <methodname>clear()</methodname> nettoie tous les anciens profils de la pile.
  158. </para>
  159. </listitem>
  160. </itemizedlist>
  161. <para>
  162. La valeur de retour de <methodname>getLastQueryProfile()</methodname> et les éléments
  163. individuels de <methodname>getQueryProfiles()</methodname> sont des objets de type
  164. <classname>Zend_Db_Profiler_Query</classname> qui permettent d'inspecter les
  165. requêtes&#160;:
  166. </para>
  167. <itemizedlist>
  168. <listitem>
  169. <para>
  170. <methodname>getQuery()</methodname> retourne le <acronym>SQL</acronym> de la
  171. requête sous forme de texte. Le texte de <acronym>SQL</acronym> d'une requête
  172. préparée avec des paramètres est le texte au moment où la requête a été
  173. préparée, donc il contient les emplacements de paramètre, mais pas les
  174. valeurs utilisées quand la déclaration est exécutée.
  175. </para>
  176. </listitem>
  177. <listitem>
  178. <para>
  179. <methodname>getQueryParams()</methodname> retourne un tableau des valeurs de
  180. paramètres utilisées lors de l'exécution d'une requête préparée. Ceci inclue à
  181. la fois les paramètres attachés et les arguments de la méthode
  182. <methodname>execute()</methodname>. Les clés du tableau sont les positions
  183. (base 1) ou les noms des paramètres.
  184. </para>
  185. </listitem>
  186. <listitem>
  187. <para>
  188. <methodname>getElapsedSecs()</methodname> retourne le nombre de secondes
  189. d'exécution de la requête.
  190. </para>
  191. </listitem>
  192. </itemizedlist>
  193. <para>
  194. L'information que <classname>Zend_Db_Profiler</classname> fourni est utile pour
  195. profiler des goulots d'étranglement dans les applications, ainsi que pour déboguer les
  196. requêtes qui viennent d'être exécutées. Par exemple, pour voir la dernière requête qui
  197. vient de s'exécuter&#160;:
  198. </para>
  199. <programlisting language="php"><![CDATA[
  200. $query = $profileur->getLastQueryProfile();
  201. echo $query->getQuery();
  202. ]]></programlisting>
  203. <para>
  204. Si une page se génère lentement, utilisez le profileur pour déterminer le nombre
  205. total de requêtes, et ensuite passer d'une requête à l'autre pour voir laquelle
  206. a été la plus longue&#160;:
  207. </para>
  208. <programlisting language="php"><![CDATA[
  209. $tempsTotal = $profileur->getTotalElapsedSecs();
  210. $nombreRequetes = $profileur->getTotalNumQueries();
  211. $tempsLePlusLong = 0;
  212. $requeteLaPlusLongue = null;
  213. foreach ($profileur->getQueryProfiles() as $query) {
  214. if ($query->getElapsedSecs() > $tempsLePlusLong) {
  215. $tempsLePlusLong = $query->getElapsedSecs();
  216. $requeteLaPlusLongue = $query->getQuery();
  217. }
  218. }
  219. echo 'Exécution de '
  220. . $nombreRequetes
  221. . ' requêtes en '
  222. . $tempsTotal
  223. . ' secondes' . "\n";
  224. echo 'Temps moyen : '
  225. . $tempsTotal / $nombreRequetes
  226. . ' secondes' . "\n";
  227. echo 'Requêtes par seconde: '
  228. . $nombreRequetes / $tempsTotal
  229. . ' seconds' . "\n";
  230. echo 'Requête la plus lente (secondes) : '
  231. . $tempsLePlusLong . "\n";
  232. echo "Requête la plus lente (SQL) : \n"
  233. . $requeteLaPlusLongue . "\n";
  234. ]]></programlisting>
  235. </sect2>
  236. <sect2 id="zend.db.profiler.advanced">
  237. <title>Utilisation avancée du profileur</title>
  238. <para>
  239. En plus de l'inspection de requête, le profileur permet aussi au développeur de
  240. filtrer quelles requêtes il veut profiler. Les méthodes suivantes fonctionnent avec une
  241. instance de <classname>Zend_Db_Profiler</classname>&#160;:
  242. </para>
  243. <sect3 id="zend.db.profiler.advanced.filtertime">
  244. <title>Filtrer par temps d'exécution</title>
  245. <para>
  246. <methodname>setFilterElapsedSecs()</methodname> permet au développeur de définir un
  247. temps minimum d'exécution de la requête avant que celle-ci soit profilée. Pour
  248. retirer le filtre, passez une valeur <constant>NULL</constant> à la méthode.
  249. </para>
  250. <programlisting language="php"><![CDATA[
  251. // Seules les requêtes qui durent au moins 5 secondes sont profilées :
  252. $profileur->setFilterElapsedSecs(5);
  253. // Profil de toutes les requêtes, peu importe leur durée :
  254. $profileur->setFilterElapsedSecs(null);
  255. ]]></programlisting>
  256. </sect3>
  257. <sect3 id="zend.db.profiler.advanced.filtertype">
  258. <title>Filtrer par type de requête</title>
  259. <para>
  260. <methodname>setFilterQueryType()</methodname> permet au développeur de définir quels
  261. types de requêtes doivent être profilées ; pour profiler des types multiples vous
  262. pouvez utiliser le OU logique. Les types de requêtes sont définis sous forme de
  263. constantes de <classname>Zend_Db_Profiler</classname>&#160;:
  264. </para>
  265. <itemizedlist>
  266. <listitem>
  267. <para>
  268. <constant>Zend_Db_Profiler::CONNECT</constant>&#160;: opérations de
  269. connexion ou de sélection de base de données.
  270. </para>
  271. </listitem>
  272. <listitem>
  273. <para>
  274. <constant>Zend_Db_Profiler::QUERY</constant>&#160;: requête générale qui
  275. ne correspond pas aux autres types.
  276. </para>
  277. </listitem>
  278. <listitem>
  279. <para>
  280. <constant>Zend_Db_Profiler::INSERT</constant>&#160;: toute requête qui
  281. ajoute des données dans la base de données, généralement
  282. du <acronym>SQL</acronym> <acronym>INSERT</acronym>.
  283. </para>
  284. </listitem>
  285. <listitem>
  286. <para>
  287. <constant>Zend_Db_Profiler::UPDATE</constant>&#160;: toute requête qui
  288. met à jour des données, généralement du <acronym>SQL</acronym>
  289. <acronym>UPDATE</acronym>.
  290. </para>
  291. </listitem>
  292. <listitem>
  293. <para>
  294. <constant>Zend_Db_Profiler::DELETE</constant>&#160;: toute requête qui
  295. efface des données, généralement du <acronym>SQL</acronym>
  296. <constant>DELETE</constant>.
  297. </para>
  298. </listitem>
  299. <listitem>
  300. <para>
  301. <constant>Zend_Db_Profiler::SELECT</constant>&#160;: toute requête qui
  302. récupère des données, généralement du <acronym>SQL</acronym>
  303. <acronym>SELECT</acronym>.
  304. </para>
  305. </listitem>
  306. <listitem>
  307. <para>
  308. <constant>Zend_Db_Profiler::TRANSACTION</constant>&#160;: toute requête
  309. qui concerne des opérations de transaction, comme start transaction,
  310. commit, ou rollback.
  311. </para>
  312. </listitem>
  313. </itemizedlist>
  314. <para>
  315. Comme avec <methodname>setFilterElapsedSecs()</methodname>, vous pouvez retirer
  316. tous les filtres en passant <constant>NULL</constant> comme unique argument.
  317. </para>
  318. <programlisting language="php"><![CDATA[
  319. // profile uniquement les requêtes SELECT
  320. $profileur->setFilterQueryType(Zend_Db_Profiler::SELECT);
  321. // profile les requêtes SELECT, INSERT, et UPDATE
  322. $profileur->setFilterQueryType(Zend_Db_Profiler::SELECT
  323. | Zend_Db_Profiler::INSERT
  324. | Zend_Db_Profiler::UPDATE);
  325. // profile les requêtes DELETE
  326. $profileur->setFilterQueryType(Zend_Db_Profiler::DELETE);
  327. // Efface tous les filtres
  328. $profileur->setFilterQueryType(null);
  329. ]]></programlisting>
  330. </sect3>
  331. <sect3 id="zend.db.profiler.advanced.getbytype">
  332. <title>Récupérer les profils par type de requête</title>
  333. <para>
  334. Utiliser <methodname>setFilterQueryType()</methodname> peut réduire les profils
  335. générés. Cependant il est parfois utile de garder tous les profils et voir
  336. uniquement ceux dont on a besoin, à un moment donné. Une autre possibilité de
  337. <methodname>getQueryProfiles()</methodname> est qu'il est possible de filtrer
  338. à la volée, en passant un type de requête (ou une combinaison logique de types
  339. de requête) comme premier argument ; voir
  340. <link linkend="zend.db.profiler.advanced.filtertype">cette section</link>
  341. pour la liste des constantes de types de requête.
  342. </para>
  343. <programlisting language="php"><![CDATA[
  344. // Récupère uniquement les profils des requêtes SELECT
  345. $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT);
  346. // Récupère uniquement les profils des requêtes :
  347. // SELECT, INSERT, et UPDATE
  348. $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT
  349. | Zend_Db_Profiler::INSERT
  350. | Zend_Db_Profiler::UPDATE);
  351. // Récupère uniquement les profils des requêtes DELETE
  352. // (on peut donc comprendre pourquoi les données disparaissent)
  353. $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::DELETE);
  354. ]]></programlisting>
  355. </sect3>
  356. </sect2>
  357. <sect2 id="zend.db.profiler.profilers">
  358. <title>Profileurs spécialisés</title>
  359. <para>
  360. Un profileur spécialisé est un objet qui hérite de
  361. <classname>Zend_Db_Profiler</classname>. Les profileurs spécialisés traitent les
  362. informations de profilage de manière spécifique.
  363. </para>
  364. <xi:include href="Zend_Db_Profiler-Firebug.xml" />
  365. </sect2>
  366. </sect1>