Zend_Db_Profiler.xml 17 KB

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