Zend_Db_Profiler.xml 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 14978 -->
  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>Einführung</title>
  8. <para>
  9. <classname>Zend_Db_Profiler</classname> kann aktiviert werden, um das Erstellen von Profilen für
  10. Abfragen zu erlauben. Die Profile enthalten die Abfragen, die durch den Adapter
  11. verarbeitet worden sind, sowie die Laufzeit der Abfragen, um die Kontrolle der
  12. verarbeiteten Abfragen zu ermöglichen, ohne das extra Code für das Debugging zu den
  13. Klassen hinzugefügt werden muß. Die erweiterte Verwendung ermöglicht den Entwickler
  14. sogar zu filtern, welche Abfragen aufgezeichnet werden sollen.
  15. </para>
  16. <para>
  17. Der Profiler wird entweder durch die Übergabe eines Parameters an den Konstruktor des
  18. Adapters oder zu einem späteren Zeitpunkt direkt an den Adapter aktiviert.
  19. </para>
  20. <programlisting role="php"><![CDATA[
  21. $params = array(
  22. 'host' => '127.0.0.1',
  23. 'username' => 'webuser',
  24. 'password' => 'xxxxxxxx',
  25. 'dbname' => 'test',
  26. 'profiler' => true // aktiviere den Profiler; false, um ihn zu
  27. // deaktivieren (standardmäßig deaktiviert)
  28. );
  29. $db = Zend_Db::factory('PDO_MYSQL', $params);
  30. // deaktiviere Profiler
  31. $db->getProfiler()->setEnabled(false);
  32. // aktiviere Profiler
  33. $db->getProfiler()->setEnabled(true);
  34. ]]>
  35. </programlisting>
  36. <para>
  37. Der Wert der <code>profiler</code> Option ist flexibel. Er wird unterschiedlich interpretiert,
  38. abhängig von seinem Typ. Meistens sollte ein einfacher Boolscher Wert verwendet werden, aber
  39. andere Typen ermöglichen es das Verhalten des Profilers anzupassen.
  40. </para>
  41. <para>
  42. Ein boolsches Argument aktiviert den Profiler wenn es der Wert <code>true</code> ist, oder schaltet
  43. ihn mit <code>false</code> aus. Die Profiler Klasse ist die Standard Profiler Klasse des Adapters
  44. <classname>Zend_Db_Profiler</classname>.
  45. <programlisting role="php"><![CDATA[
  46. $params['profiler'] = true;
  47. $db = Zend_Db::factory('PDO_MYSQL', $params);
  48. ]]>
  49. </programlisting>
  50. </para>
  51. <para>
  52. Eine Instanz eines Profiler Objektes führt dazu das der Adapter dieses Objekt verwendet. Der
  53. Typ des Objektes muß hierfür <classname>Zend_Db_Profiler</classname> oder eine Subklasse sein.
  54. Der Profiler muß separat eingeschaltet werden.
  55. <programlisting role="php"><![CDATA[
  56. $profiler = MyProject_Db_Profiler();
  57. $profiler->setEnabled(true);
  58. $params['profiler'] = $profiler;
  59. $db = Zend_Db::factory('PDO_MYSQL', $params);
  60. ]]>
  61. </programlisting>
  62. </para>
  63. <para>
  64. Ein Argument kann ein assoziatives Array sein das eines oder alle der folgenden Schlüssel enthält:
  65. '<code>enabled</code>', '<code>instance</code>', oder '<code>class</code>'. Die '<code>enabled</code>'
  66. und '<code>instance</code>' Schlüssel korrespondieren zu den zuvor dokumentierten boolschen und Instanz
  67. Typen. Der '<code>class</code>' Schlüssel wird verwendet um die Klasse die für einen eigenen Profiler
  68. verwendet werden soll, zu benennen. Die Klasse muß <classname>Zend_Db_Profiler</classname> oder eine
  69. Subklasse sein. Die Klasse wird ohne Konstruktor Argumente instanziert. Die '<code>class</code>'
  70. Option wird ignoriert wenn die '<code>instance</code>' Option angegeben wurde.
  71. <programlisting role="php"><![CDATA[
  72. $params['profiler'] = array(
  73. 'enabled' => true,
  74. 'class' => 'MyProject_Db_Profiler'
  75. );
  76. $db = Zend_Db::factory('PDO_MYSQL', $params);
  77. ]]>
  78. </programlisting>
  79. </para>
  80. <para>
  81. Letztendlich kann das Argument ein Objekt des Typs <classname>Zend_Config</classname> sein das
  82. Eigenschaften enthält welche als Array Schlüssel verwendet werden wie anbei beschrieben.
  83. Zum Beispiel könnte die Datei "config.ini" die folgenden Daten enthalten:
  84. <programlisting role="php"><![CDATA[
  85. [main]
  86. db.profiler.class = "MyProject_Db_Profiler"
  87. db.profiler.enabled = true
  88. ]]>
  89. </programlisting>
  90. Diese Konfiguration kann durch den folgenden PHP Code angesprochen werden:
  91. <programlisting role="php"><![CDATA[
  92. $config = new Zend_Config_Ini('config.ini', 'main');
  93. $params['profiler'] = $config->db->profiler;
  94. $db = Zend_Db::factory('PDO_MYSQL', $params);
  95. ]]>
  96. </programlisting>
  97. Die '<code>instance</code>' Eigenschaft kann wie folgt verwendet werden:
  98. <programlisting role="php"><![CDATA[
  99. $profiler = new MyProject_Db_Profiler();
  100. $profiler->setEnabled(true);
  101. $configData = array(
  102. 'instance' => $profiler
  103. );
  104. $config = new Zend_Config($configData);
  105. $params['profiler'] = $config;
  106. $db = Zend_Db::factory('PDO_MYSQL', $params);
  107. ]]>
  108. </programlisting>
  109. </para>
  110. </sect2>
  111. <sect2 id="zend.db.profiler.using">
  112. <title>Den Profiler verwenden</title>
  113. <para>
  114. Der Profiler kann jederzeit über die Adapter Methode <code>getProfiler()</code> geholt
  115. werden:
  116. </para>
  117. <programlisting role="php"><![CDATA[
  118. $profiler = $db->getProfiler();
  119. ]]>
  120. </programlisting>
  121. <para>
  122. Dies gibt eine <classname>Zend_Db_Profiler</classname> Objektinstanz zurück. Mit dieser Instanz
  123. kann der Entwickler seine Abfragen mit Hilfe von verschiedenen Methoden untersuchen:
  124. </para>
  125. <itemizedlist>
  126. <listitem>
  127. <para>
  128. <code>getTotalNumQueries()</code> gibt die Gesamtzeit aller aufgezeichneten
  129. Abfragen zurück.
  130. </para>
  131. </listitem>
  132. <listitem>
  133. <para>
  134. <code>getTotalElapsedSecs()</code> gibt die gesamte Anzahl an Sekunden
  135. für alle aufgezeichneten Abfragen zurück.
  136. </para>
  137. </listitem>
  138. <listitem>
  139. <para>
  140. <code>getQueryProfiles()</code> gibt ein Array mit allen aufgezeichneten
  141. Abfragen zurück.
  142. </para>
  143. </listitem>
  144. <listitem>
  145. <para>
  146. <code>getLastQueryProfile()</code> gibt das Profil der letzten (neuesten)
  147. Abfrage zurück, gleichgültig ob die Abfrage beendet werden konnte oder nicht (wenn
  148. nicht, wird die Endzeit null sein)
  149. </para>
  150. </listitem>
  151. <listitem>
  152. <para>
  153. <code>clear()</code> löscht jedes vorherige Abfrageprofile vom Stapel.
  154. </para>
  155. </listitem>
  156. </itemizedlist>
  157. <para>
  158. Der Rückgabewert von <code>getLastQueryProfile()</code> und die einzelnen Elemente von
  159. <code>getQueryProfiles()</code> sind <classname>Zend_Db_Profiler_Query</classname> Objekte, welche
  160. die Möglichkeit bieten, die individuellen Abfragen zu untersuchen:
  161. </para>
  162. <itemizedlist>
  163. <listitem>
  164. <para>
  165. <code>getQuery()</code> gibt den SQL Text der Abfrage zurück.
  166. Der SQL Text des vorbereiteten Statements mit Parametern ist der Text, zu der Zeit
  167. als die Abfrage vorbereitet wurde, er enthält also Platzhalter für Parameter, nicht die
  168. Werte die verwendet werden wenn das Statement ausgeführt wird.
  169. </para>
  170. </listitem>
  171. <listitem>
  172. <para>
  173. <code>getQueryParams()</code> gibt ein Array von Parameter Werten zurück die verwendet werden
  174. wenn eine vorbereitete Abfrage ausgeführt wird. Das beinhaltet beide, gebundene Parameter und
  175. Argumente für die <code>execute()</code> Methode des Statements. Die Schlüssel des Arrays sind
  176. die Positionierten (1-basierend) oder benannten (Zeichenkette) Parameter Indezes.
  177. </para>
  178. </listitem>
  179. <listitem>
  180. <para>
  181. <code>getElapsedSecs()</code> gibt die Anzahl der Sekunden zurück, wie lange
  182. die Abfrage gelaufen ist.
  183. </para>
  184. </listitem>
  185. </itemizedlist>
  186. <para>
  187. Die Informationen, die <classname>Zend_Db_Profiler</classname> bereitstellt, sind nützlich, um
  188. Engpässe in der Anwendung zu ermitteln und um Abfragen zu überprüfen, die durchgeführt
  189. worden sind. Um zum Beispiel die genaue Abfrage zu sehen, die zuletzt durchgeführt
  190. worden ist:
  191. </para>
  192. <programlisting role="php"><![CDATA[
  193. $query = $profiler->getLastQueryProfile();
  194. echo $query->getQuery();
  195. ]]>
  196. </programlisting>
  197. <para>
  198. Vielleicht wird eine Seite langsam erstellt; verwende den Profiler, um zuerst die
  199. gesamte Laufzeit aller Abfragen zu ermitteln und dann durchlaufe die Abfragen, um die
  200. am längsten laufende zu finden:
  201. </para>
  202. <programlisting role="php"><![CDATA[
  203. $totalTime = $profiler->getTotalElapsedSecs();
  204. $queryCount = $profiler->getTotalNumQueries();
  205. $longestTime = 0;
  206. $longestQuery = null;
  207. foreach ($profiler->getQueryProfiles() as $query) {
  208. if ($query->getElapsedSecs() > $longestTime) {
  209. $longestTime = $query->getElapsedSecs();
  210. $longestQuery = $query->getQuery();
  211. }
  212. }
  213. echo 'Executed ' . $queryCount . ' queries in ' . $totalTime .
  214. ' seconds' . "\n";
  215. echo 'Average query length: ' . $totalTime / $queryCount .
  216. ' seconds' . "\n";
  217. echo 'Queries per second: ' . $queryCount / $totalTime . "\n";
  218. echo 'Longest query length: ' . $longestTime . "\n";
  219. echo "Longest query: \n" . $longestQuery . "\n";
  220. ]]>
  221. </programlisting>
  222. </sect2>
  223. <sect2 id="zend.db.profiler.advanced">
  224. <title>Fortgeschrittene Profiler Verwendung</title>
  225. <para>
  226. Zusätzlich zum Untersuchen von Anfragen erlaubt der Profiler dem Entwickler auch zu
  227. filtern, welche Abfragen aufgezeichnet werden sollen. Die folgenden Methoden arbeiten
  228. mit einer <classname>Zend_Db_Profiler</classname> Instanz:
  229. </para>
  230. <sect3 id="zend.db.profiler.advanced.filtertime">
  231. <title>Filtern anhand der Laufzeit der Abfragen</title>
  232. <para>
  233. <code>setFilterElapsedSecs()</code> ermöglicht dem Entwickler, einen minimale
  234. Laufzeit anzugeben, bevor eine Abfrage aufzeichnet werden soll. Um den Filter zu
  235. entfernen, muss nur der Wert null an die Methode übergeben werden.
  236. </para>
  237. <programlisting role="php"><![CDATA[
  238. // Zeichne nur Abfragen auf, die mindestens 5 Sekunden laufen:
  239. $profiler->setFilterElapsedSecs(5);
  240. // Zeichne alle Abfragen unabhängig von deren Laufzeit auf:
  241. $profiler->setFilterElapsedSecs(null);
  242. ]]>
  243. </programlisting>
  244. </sect3>
  245. <sect3 id="zend.db.profiler.advanced.filtertype">
  246. <title>Filtern anhand des Abfragetyp</title>
  247. <para>
  248. <code>setFilterQueryType()</code> ermöglicht dem Entwickler anzugeben, welche
  249. Abfragetypen aufgezeichnet werden sollen; um mehrere Typen aufzuzeichnen, verwende
  250. das logische OR. Abfragetypen sind mit den folgenden
  251. <classname>Zend_Db_Profiler</classname> Konstanten definiert:
  252. </para>
  253. <itemizedlist>
  254. <listitem>
  255. <para>
  256. <classname>Zend_Db_Profiler::CONNECT</classname>: Verbindungsoperationen oder
  257. Auswahl einer Datenbank .
  258. </para>
  259. </listitem>
  260. <listitem>
  261. <para>
  262. <classname>Zend_Db_Profiler::QUERY</classname>: allgemeine Datenbankabfragen, die
  263. keinem der anderen Typen entsprechen.
  264. </para>
  265. </listitem>
  266. <listitem>
  267. <para>
  268. <classname>Zend_Db_Profiler::INSERT</classname>: jede Abfrage, die neue Daten zur
  269. Datenbank hinzufügt, normalerweise ein SQL INSERT.
  270. </para>
  271. </listitem>
  272. <listitem>
  273. <para>
  274. <classname>Zend_Db_Profiler::UPDATE</classname>: jede Abfrage, die vorhandene Daten
  275. aktualisiert, normalerweise ein SQL UPDATE.
  276. </para>
  277. </listitem>
  278. <listitem>
  279. <para>
  280. <classname>Zend_Db_Profiler::DELETE</classname>: jede Abfrage, die vorhandene Daten
  281. löscht, normalerweise ein SQL DELETE.
  282. </para>
  283. </listitem>
  284. <listitem>
  285. <para>
  286. <classname>Zend_Db_Profiler::SELECT</classname>: jede Abfrage, die vorhandene Daten
  287. selektiert, normalerweise ein SQL SELECT.
  288. </para>
  289. </listitem>
  290. <listitem>
  291. <para>
  292. <classname>Zend_Db_Profiler::TRANSACTION</classname>: jede Transaktionsoperation,
  293. wie zum Beispiel START TRANSACTION, COMMIT oder ROLLBACK.
  294. </para>
  295. </listitem>
  296. </itemizedlist>
  297. <para>
  298. Mit <code>setFilterElapsedSecs()</code> kannst du jeden vorhandenen Filtern
  299. entfernen, indem du <code>null</code> als einziges Argument übergibst.
  300. </para>
  301. <programlisting role="php"><![CDATA[
  302. // zeichne nur SELECT Abfragen auf
  303. $profiler->setFilterQueryType(Zend_Db_Profiler::SELECT);
  304. // zeichne SELECT, INSERT und UPDATE Abfragen auf
  305. $profiler->setFilterQueryType(Zend_Db_Profiler::SELECT |
  306. Zend_Db_Profiler::INSERT |
  307. Zend_Db_Profiler::UPDATE);
  308. // zeichne DELETE Abfragen auf
  309. $profiler->setFilterQueryType(Zend_Db_Profiler::DELETE);
  310. // Remove all filters
  311. $profiler->setFilterQueryType(null);
  312. ]]>
  313. </programlisting>
  314. </sect3>
  315. <sect3 id="zend.db.profiler.advanced.getbytype">
  316. <title>Hole Profil nach Abfragetyp zurück</title>
  317. <para>
  318. Die Verwendung von <code>setFilterQueryType()</code> kann die Anzahl der
  319. aufgezeichneten Abfragen reduzieren. Allerdings kann es sinnvoller sein, alle
  320. Abfragen auzuzeichnen, baer nur diese anzuschauen, die im Moment gebraucht werden.
  321. Ein weiteres Feature von <code>getQueryProfiles()</code> ist das Filtern der
  322. Abfragen "on-the-fly" durch Übergabe eines Abfragetyps (oder eine logischen
  323. Kombination von Abfragetypen) als erstes Argument; beachte
  324. <xref linkend="zend.db.profiler.advanced.filtertype" /> für eine Liste der
  325. Konstanten für Abfragetypen.
  326. </para>
  327. <programlisting role="php"><![CDATA[
  328. // Hole nur SELECT Abfragen zurück
  329. $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT);
  330. // Hole nur SELECT, INSERT un UPDATE Abfragen zurück
  331. $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT |
  332. Zend_Db_Profiler::INSERT |
  333. Zend_Db_Profiler::UPDATE);
  334. // Hole DELETE Abfragen zurück
  335. $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::DELETE);
  336. ]]>
  337. </programlisting>
  338. </sect3>
  339. </sect2>
  340. <sect2 id="zend.db.profiler.profilers">
  341. <title>Specialized Profilers</title>
  342. <para>
  343. Ein spezialisierter Profiler ist ein Objekt das von <classname>Zend_Db_Profiler</classname> abgeleitet ist.
  344. Spezialisierte Profiler behandeln die Profilinginformationen auf speziellen Wegen.
  345. </para>
  346. <xi:include href="Zend_Db_Profiler-Firebug.xml" />
  347. </sect2>
  348. </sect1>
  349. <!--
  350. vim:se ts=4 sw=4 et:
  351. -->