Zend_Db_Profiler.xml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect1 id="zend.db.profiler" xmlns:xi="http://www.w3.org/2001/XInclude">
  4. <title>Zend_Db_Profiler</title>
  5. <sect2 id="zend.db.profiler.introduction">
  6. <title>Introduction</title>
  7. <para>
  8. <classname>Zend_Db_Profiler</classname> can be enabled to allow profiling of
  9. queries. Profiles include the queries processed by the adapter as
  10. well as elapsed time to run the queries, allowing inspection of the
  11. queries that have been performed without needing to add extra
  12. debugging code to classes. Advanced usage also allows the
  13. developer to filter which queries are profiled.
  14. </para>
  15. <para>
  16. Enable the profiler by either passing a directive to the adapter
  17. constructor, or by asking the adapter to enable it later.
  18. </para>
  19. <programlisting language="php"><![CDATA[
  20. $params = array(
  21. 'host' => '127.0.0.1',
  22. 'username' => 'webuser',
  23. 'password' => 'xxxxxxxx',
  24. 'dbname' => 'test'
  25. 'profiler' => true // turn on profiler
  26. // set to false to disable (disabled by default)
  27. );
  28. $db = Zend_Db::factory('PDO_MYSQL', $params);
  29. // turn off profiler:
  30. $db->getProfiler()->setEnabled(false);
  31. // turn on profiler:
  32. $db->getProfiler()->setEnabled(true);
  33. ]]></programlisting>
  34. <para>
  35. The value of the '<code>profiler</code>' option is flexible. It is interpreted
  36. differently depending on its type. Most often, you should use a simple boolean value,
  37. but other types enable you to customize the profiler behavior.
  38. </para>
  39. <para>
  40. A boolean argument sets the profiler to enabled if it is a <constant>TRUE</constant>
  41. value, or disabled if <constant>FALSE</constant>. The profiler class is the adapter's
  42. default profiler class, <classname>Zend_Db_Profiler</classname>.
  43. <programlisting language="php"><![CDATA[
  44. $params['profiler'] = true;
  45. $db = Zend_Db::factory('PDO_MYSQL', $params);
  46. ]]></programlisting>
  47. </para>
  48. <para>
  49. An instance of a profiler object makes the adapter use that object. The object type must
  50. be <classname>Zend_Db_Profiler</classname> or a subclass thereof. Enabling the profiler
  51. is done separately.
  52. <programlisting language="php"><![CDATA[
  53. $profiler = MyProject_Db_Profiler();
  54. $profiler->setEnabled(true);
  55. $params['profiler'] = $profiler;
  56. $db = Zend_Db::factory('PDO_MYSQL', $params);
  57. ]]></programlisting>
  58. </para>
  59. <para>
  60. The argument can be an associative array containing any or all of the keys
  61. '<code>enabled</code>', '<code>instance</code>', and '<code>class</code>'. The
  62. '<code>enabled</code>' and '<code>instance</code>' keys correspond to the boolean and
  63. instance types documented above. The '<code>class</code>' key is used to name a class to
  64. use for a custom profiler. The class must be <classname>Zend_Db_Profiler</classname> or
  65. a subclass. The class is instantiated with no constructor arguments. The
  66. '<code>class</code>' option is ignored when the '<code>instance</code>' option is
  67. supplied.
  68. <programlisting language="php"><![CDATA[
  69. $params['profiler'] = array(
  70. 'enabled' => true,
  71. 'class' => 'MyProject_Db_Profiler'
  72. );
  73. $db = Zend_Db::factory('PDO_MYSQL', $params);
  74. ]]></programlisting>
  75. </para>
  76. <para>
  77. Finally, the argument can be an object of type <classname>Zend_Config</classname>
  78. containing properties, which are treated as the array keys described above. For example,
  79. a file "config.ini" might contain the following data:
  80. <programlisting language="ini"><![CDATA[
  81. [main]
  82. db.profiler.class = "MyProject_Db_Profiler"
  83. db.profiler.enabled = true
  84. ]]></programlisting>
  85. This configuration can be applied by the following PHP code:
  86. <programlisting language="php"><![CDATA[
  87. $config = new Zend_Config_Ini('config.ini', 'main');
  88. $params['profiler'] = $config->db->profiler;
  89. $db = Zend_Db::factory('PDO_MYSQL', $params);
  90. ]]></programlisting>
  91. The '<code>instance</code>' property may be used as in the following:
  92. <programlisting language="php"><![CDATA[
  93. $profiler = new MyProject_Db_Profiler();
  94. $profiler->setEnabled(true);
  95. $configData = array(
  96. 'instance' => $profiler
  97. );
  98. $config = new Zend_Config($configData);
  99. $params['profiler'] = $config;
  100. $db = Zend_Db::factory('PDO_MYSQL', $params);
  101. ]]></programlisting>
  102. </para>
  103. </sect2>
  104. <sect2 id="zend.db.profiler.using">
  105. <title>Using the Profiler</title>
  106. <para>
  107. At any point, grab the profiler using the adapter's
  108. <code>getProfiler()</code> method:
  109. </para>
  110. <programlisting language="php"><![CDATA[
  111. $profiler = $db->getProfiler();
  112. ]]></programlisting>
  113. <para>
  114. This returns a <classname>Zend_Db_Profiler</classname> object instance. With
  115. that instance, the developer can examine your queries using a
  116. variety of methods:
  117. </para>
  118. <itemizedlist>
  119. <listitem>
  120. <para>
  121. <code>getTotalNumQueries()</code> returns the total number
  122. of queries that have been profiled.
  123. </para>
  124. </listitem>
  125. <listitem>
  126. <para>
  127. <code>getTotalElapsedSecs()</code> returns the total
  128. number of seconds elapsed for all profiled queries.
  129. </para>
  130. </listitem>
  131. <listitem>
  132. <para>
  133. <code>getQueryProfiles()</code> returns an array of all
  134. query profiles.
  135. </para>
  136. </listitem>
  137. <listitem>
  138. <para>
  139. <code>getLastQueryProfile()</code> returns the last (most
  140. recent) query profile, regardless of whether or not the query
  141. has finished (if it hasn't, the end time will be null)
  142. </para>
  143. </listitem>
  144. <listitem>
  145. <para>
  146. <code>clear()</code> clears any past query profiles
  147. from the stack.
  148. </para>
  149. </listitem>
  150. </itemizedlist>
  151. <para>
  152. The return value of <code>getLastQueryProfile()</code> and the
  153. individual elements of <code>getQueryProfiles()</code> are
  154. <classname>Zend_Db_Profiler_Query</classname> objects, which provide the
  155. ability to inspect the individual queries themselves:
  156. </para>
  157. <itemizedlist>
  158. <listitem>
  159. <para>
  160. <code>getQuery()</code> returns the SQL text of the query.
  161. The SQL text of a prepared statement with parameters is the
  162. text at the time the query was prepared, so it contains
  163. parameter placeholders, not the values used when the
  164. statement is executed.
  165. </para>
  166. </listitem>
  167. <listitem>
  168. <para>
  169. <code>getQueryParams()</code> returns an array of
  170. parameter values used when executing a prepared query.
  171. This includes both bound parameters and arguments to the
  172. statement's <code>execute()</code> method. The keys of
  173. the array are the positional (1-based) or named (string)
  174. parameter indices.
  175. </para>
  176. </listitem>
  177. <listitem>
  178. <para>
  179. <code>getElapsedSecs()</code> returns the number of
  180. seconds the query ran.
  181. </para>
  182. </listitem>
  183. </itemizedlist>
  184. <para>
  185. The information <classname>Zend_Db_Profiler</classname> provides is useful for
  186. profiling bottlenecks in applications, and for debugging queries
  187. that have been run. For instance, to see the exact query that was
  188. last run:
  189. </para>
  190. <programlisting language="php"><![CDATA[
  191. $query = $profiler->getLastQueryProfile();
  192. echo $query->getQuery();
  193. ]]></programlisting>
  194. <para>
  195. Perhaps a page is generating slowly; use the profiler to determine
  196. first the total number of seconds of all queries, and then step
  197. through the queries to find the one that ran longest:
  198. </para>
  199. <programlisting language="php"><![CDATA[
  200. $totalTime = $profiler->getTotalElapsedSecs();
  201. $queryCount = $profiler->getTotalNumQueries();
  202. $longestTime = 0;
  203. $longestQuery = null;
  204. foreach ($profiler->getQueryProfiles() as $query) {
  205. if ($query->getElapsedSecs() > $longestTime) {
  206. $longestTime = $query->getElapsedSecs();
  207. $longestQuery = $query->getQuery();
  208. }
  209. }
  210. echo 'Executed ' . $queryCount . ' queries in ' . $totalTime .
  211. ' seconds' . "\n";
  212. echo 'Average query length: ' . $totalTime / $queryCount .
  213. ' seconds' . "\n";
  214. echo 'Queries per second: ' . $queryCount / $totalTime . "\n";
  215. echo 'Longest query length: ' . $longestTime . "\n";
  216. echo "Longest query: \n" . $longestQuery . "\n";
  217. ]]></programlisting>
  218. </sect2>
  219. <sect2 id="zend.db.profiler.advanced">
  220. <title>Advanced Profiler Usage</title>
  221. <para>
  222. In addition to query inspection, the profiler also allows the
  223. developer to filter which queries get profiled. The following
  224. methods operate on a <classname>Zend_Db_Profiler</classname> instance:
  225. </para>
  226. <sect3 id="zend.db.profiler.advanced.filtertime">
  227. <title>Filter by query elapsed time</title>
  228. <para>
  229. <code>setFilterElapsedSecs()</code> allows the developer to set
  230. a minimum query time before a query is profiled. To remove the
  231. filter, pass the method a null value.
  232. </para>
  233. <programlisting language="php"><![CDATA[
  234. // Only profile queries that take at least 5 seconds:
  235. $profiler->setFilterElapsedSecs(5);
  236. // Profile all queries regardless of length:
  237. $profiler->setFilterElapsedSecs(null);
  238. ]]></programlisting>
  239. </sect3>
  240. <sect3 id="zend.db.profiler.advanced.filtertype">
  241. <title>Filter by query type</title>
  242. <para>
  243. <code>setFilterQueryType()</code> allows the developer to set
  244. which types of queries should be profiled; to profile multiple
  245. types, logical OR them. Query types are defined as the following
  246. <classname>Zend_Db_Profiler</classname> constants:
  247. </para>
  248. <itemizedlist>
  249. <listitem>
  250. <para>
  251. <classname>Zend_Db_Profiler::CONNECT</classname>: connection
  252. operations, or selecting a database.
  253. </para>
  254. </listitem>
  255. <listitem>
  256. <para>
  257. <classname>Zend_Db_Profiler::QUERY</classname>: general database
  258. queries that do not match other types.
  259. </para>
  260. </listitem>
  261. <listitem>
  262. <para>
  263. <classname>Zend_Db_Profiler::INSERT</classname>: any query that
  264. adds new data to the database, generally SQL INSERT.
  265. </para>
  266. </listitem>
  267. <listitem>
  268. <para>
  269. <classname>Zend_Db_Profiler::UPDATE</classname>: any query that
  270. updates existing data, usually SQL UPDATE.
  271. </para>
  272. </listitem>
  273. <listitem>
  274. <para>
  275. <classname>Zend_Db_Profiler::DELETE</classname>: any query that
  276. deletes existing data, usually SQL DELETE.
  277. </para>
  278. </listitem>
  279. <listitem>
  280. <para>
  281. <classname>Zend_Db_Profiler::SELECT</classname>: any query that
  282. retrieves existing data, usually SQL SELECT.
  283. </para>
  284. </listitem>
  285. <listitem>
  286. <para>
  287. <classname>Zend_Db_Profiler::TRANSACTION</classname>: any
  288. transactional operation, such as start transaction, commit,
  289. or rollback.
  290. </para>
  291. </listitem>
  292. </itemizedlist>
  293. <para>
  294. As with <code>setFilterElapsedSecs()</code>, you can remove any
  295. existing filters by passing <constant>NULL</constant> as the sole
  296. argument.
  297. </para>
  298. <programlisting language="php"><![CDATA[
  299. // profile only SELECT queries
  300. $profiler->setFilterQueryType(Zend_Db_Profiler::SELECT);
  301. // profile SELECT, INSERT, and UPDATE queries
  302. $profiler->setFilterQueryType(Zend_Db_Profiler::SELECT |
  303. Zend_Db_Profiler::INSERT |
  304. Zend_Db_Profiler::UPDATE);
  305. // profile DELETE queries
  306. $profiler->setFilterQueryType(Zend_Db_Profiler::DELETE);
  307. // Remove all filters
  308. $profiler->setFilterQueryType(null);
  309. ]]></programlisting>
  310. </sect3>
  311. <sect3 id="zend.db.profiler.advanced.getbytype">
  312. <title>Retrieve profiles by query type</title>
  313. <para>
  314. Using <code>setFilterQueryType()</code> can cut down on the
  315. profiles generated. However, sometimes it can be more useful to
  316. keep all profiles, but view only those you need at a given
  317. moment. Another feature of <code>getQueryProfiles()</code> is
  318. that it can do this filtering on-the-fly, by passing a query
  319. type (or logical combination of query types) as its first
  320. argument; see <xref linkend="zend.db.profiler.advanced.filtertype" />
  321. for a list of the query type constants.
  322. </para>
  323. <programlisting language="php"><![CDATA[
  324. // Retrieve only SELECT query profiles
  325. $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT);
  326. // Retrieve only SELECT, INSERT, and UPDATE query profiles
  327. $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT |
  328. Zend_Db_Profiler::INSERT |
  329. Zend_Db_Profiler::UPDATE);
  330. // Retrieve DELETE query profiles
  331. $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::DELETE);
  332. ]]></programlisting>
  333. </sect3>
  334. </sect2>
  335. <sect2 id="zend.db.profiler.profilers">
  336. <title>Specialized Profilers</title>
  337. <para>
  338. A Specialized Profiler is an object that inherits from
  339. <classname>Zend_Db_Profiler</classname>. Specialized Profilers treat
  340. profiling information in specific ways.
  341. </para>
  342. <xi:include href="Zend_Db_Profiler-Firebug.xml" />
  343. </sect2>
  344. </sect1>
  345. <!--
  346. vim:se ts=4 sw=4 et:
  347. -->