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