| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- Reviewed: no -->
- <sect1 id="zend.db.profiler" xmlns:xi="http://www.w3.org/2001/XInclude">
- <title>Zend_Db_Profiler</title>
- <sect2 id="zend.db.profiler.introduction">
- <title>Introduction</title>
- <para>
- <classname>Zend_Db_Profiler</classname> can be enabled to allow profiling of
- queries. Profiles include the queries processed by the adapter as
- well as elapsed time to run the queries, allowing inspection of the
- queries that have been performed without needing to add extra
- debugging code to classes. Advanced usage also allows the
- developer to filter which queries are profiled.
- </para>
- <para>
- Enable the profiler by either passing a directive to the adapter
- constructor, or by asking the adapter to enable it later.
- </para>
- <programlisting language="php"><![CDATA[
- $params = array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test'
- 'profiler' => true // turn on profiler
- // set to false to disable (disabled by default)
- );
- $db = Zend_Db::factory('PDO_MYSQL', $params);
- // turn off profiler:
- $db->getProfiler()->setEnabled(false);
- // turn on profiler:
- $db->getProfiler()->setEnabled(true);
- ]]></programlisting>
- <para>
- The value of the '<property>profiler</property>' option is flexible. It is interpreted
- differently depending on its type. Most often, you should use a simple boolean value,
- but other types enable you to customize the profiler behavior.
- </para>
- <para>
- A boolean argument sets the profiler to enabled if it is a <constant>TRUE</constant>
- value, or disabled if <constant>FALSE</constant>. The profiler class is the adapter's
- default profiler class, <classname>Zend_Db_Profiler</classname>.
- </para>
- <programlisting language="php"><![CDATA[
- $params['profiler'] = true;
- $db = Zend_Db::factory('PDO_MYSQL', $params);
- ]]></programlisting>
- <para>
- An instance of a profiler object makes the adapter use that object. The object type must
- be <classname>Zend_Db_Profiler</classname> or a subclass thereof. Enabling the profiler
- is done separately.
- </para>
- <programlisting language="php"><![CDATA[
- $profiler = MyProject_Db_Profiler();
- $profiler->setEnabled(true);
- $params['profiler'] = $profiler;
- $db = Zend_Db::factory('PDO_MYSQL', $params);
- ]]></programlisting>
- <para>
- The argument can be an associative array containing any or all of the keys
- '<property>enabled</property>', '<property>instance</property>', and
- '<property>class</property>'. The '<property>enabled</property>' and
- '<property>instance</property>' keys correspond to the boolean and instance types
- documented above. The '<property>class</property>' key is used to name a class to
- use for a custom profiler. The class must be <classname>Zend_Db_Profiler</classname> or
- a subclass. The class is instantiated with no constructor arguments. The
- '<property>class</property>' option is ignored when the '<property>instance</property>'
- option is supplied.
- </para>
- <programlisting language="php"><![CDATA[
- $params['profiler'] = array(
- 'enabled' => true,
- 'class' => 'MyProject_Db_Profiler'
- );
- $db = Zend_Db::factory('PDO_MYSQL', $params);
- ]]></programlisting>
- <para>
- Finally, the argument can be an object of type <classname>Zend_Config</classname>
- containing properties, which are treated as the array keys described above. For example,
- a file "<filename>config.ini</filename>" might contain the following data:
- </para>
- <programlisting language="ini"><![CDATA[
- [main]
- db.profiler.class = "MyProject_Db_Profiler"
- db.profiler.enabled = true
- ]]></programlisting>
- <para>
- This configuration can be applied by the following <acronym>PHP</acronym> code:
- </para>
- <programlisting language="php"><![CDATA[
- $config = new Zend_Config_Ini('config.ini', 'main');
- $params['profiler'] = $config->db->profiler;
- $db = Zend_Db::factory('PDO_MYSQL', $params);
- ]]></programlisting>
- <para>
- The '<property>instance</property>' property may be used as in the following:
- </para>
- <programlisting language="php"><![CDATA[
- $profiler = new MyProject_Db_Profiler();
- $profiler->setEnabled(true);
- $configData = array(
- 'instance' => $profiler
- );
- $config = new Zend_Config($configData);
- $params['profiler'] = $config;
- $db = Zend_Db::factory('PDO_MYSQL', $params);
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.db.profiler.using">
- <title>Using the Profiler</title>
- <para>
- At any point, grab the profiler using the adapter's
- <methodname>getProfiler()</methodname> method:
- </para>
- <programlisting language="php"><![CDATA[
- $profiler = $db->getProfiler();
- ]]></programlisting>
- <para>
- This returns a <classname>Zend_Db_Profiler</classname> object instance. With
- that instance, the developer can examine your queries using a
- variety of methods:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>getTotalNumQueries()</methodname> returns the total number
- of queries that have been profiled.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getTotalElapsedSecs()</methodname> returns the total
- number of seconds elapsed for all profiled queries.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getQueryProfiles()</methodname> returns an array of all
- query profiles.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getLastQueryProfile()</methodname> returns the last (most
- recent) query profile, regardless of whether or not the query
- has finished (if it hasn't, the end time will be <constant>NULL</constant>)
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>clear()</methodname> clears any past query profiles
- from the stack.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- The return value of <methodname>getLastQueryProfile()</methodname> and the
- individual elements of <methodname>getQueryProfiles()</methodname> are
- <classname>Zend_Db_Profiler_Query</classname> objects, which provide the
- ability to inspect the individual queries themselves:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>getQuery()</methodname> returns the <acronym>SQL</acronym> text of
- the query. The <acronym>SQL</acronym> text of a prepared statement with
- parameters is the text at the time the query was prepared, so it contains
- parameter placeholders, not the values used when the
- statement is executed.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getQueryParams()</methodname> returns an array of
- parameter values used when executing a prepared query.
- This includes both bound parameters and arguments to the
- statement's <methodname>execute()</methodname> method. The keys of
- the array are the positional (1-based) or named (string)
- parameter indices.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>getElapsedSecs()</methodname> returns the number of
- seconds the query ran.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- The information <classname>Zend_Db_Profiler</classname> provides is useful for
- profiling bottlenecks in applications, and for debugging queries
- that have been run. For instance, to see the exact query that was
- last run:
- </para>
- <programlisting language="php"><![CDATA[
- $query = $profiler->getLastQueryProfile();
- echo $query->getQuery();
- ]]></programlisting>
- <para>
- Perhaps a page is generating slowly; use the profiler to determine
- first the total number of seconds of all queries, and then step
- through the queries to find the one that ran longest:
- </para>
- <programlisting language="php"><![CDATA[
- $totalTime = $profiler->getTotalElapsedSecs();
- $queryCount = $profiler->getTotalNumQueries();
- $longestTime = 0;
- $longestQuery = null;
- foreach ($profiler->getQueryProfiles() as $query) {
- if ($query->getElapsedSecs() > $longestTime) {
- $longestTime = $query->getElapsedSecs();
- $longestQuery = $query->getQuery();
- }
- }
- echo 'Executed ' . $queryCount . ' queries in ' . $totalTime .
- ' seconds' . "\n";
- echo 'Average query length: ' . $totalTime / $queryCount .
- ' seconds' . "\n";
- echo 'Queries per second: ' . $queryCount / $totalTime . "\n";
- echo 'Longest query length: ' . $longestTime . "\n";
- echo "Longest query: \n" . $longestQuery . "\n";
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.db.profiler.advanced">
- <title>Advanced Profiler Usage</title>
- <para>
- In addition to query inspection, the profiler also allows the
- developer to filter which queries get profiled. The following
- methods operate on a <classname>Zend_Db_Profiler</classname> instance:
- </para>
- <sect3 id="zend.db.profiler.advanced.filtertime">
- <title>Filter by query elapsed time</title>
- <para>
- <methodname>setFilterElapsedSecs()</methodname> allows the developer to set
- a minimum query time before a query is profiled. To remove the
- filter, pass the method a <constant>NULL</constant> value.
- </para>
- <programlisting language="php"><![CDATA[
- // Only profile queries that take at least 5 seconds:
- $profiler->setFilterElapsedSecs(5);
- // Profile all queries regardless of length:
- $profiler->setFilterElapsedSecs(null);
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.db.profiler.advanced.filtertype">
- <title>Filter by query type</title>
- <para>
- <methodname>setFilterQueryType()</methodname> allows the developer to set
- which types of queries should be profiled; to profile multiple
- types, logical OR them. Query types are defined as the following
- <classname>Zend_Db_Profiler</classname> constants:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <constant>Zend_Db_Profiler::CONNECT</constant>: connection
- operations, or selecting a database.
- </para>
- </listitem>
- <listitem>
- <para>
- <constant>Zend_Db_Profiler::QUERY</constant>: general database
- queries that do not match other types.
- </para>
- </listitem>
- <listitem>
- <para>
- <constant>Zend_Db_Profiler::INSERT</constant>: any query that
- adds new data to the database, generally <acronym>SQL</acronym>
- <acronym>INSERT</acronym>.
- </para>
- </listitem>
- <listitem>
- <para>
- <constant>Zend_Db_Profiler::UPDATE</constant>: any query that
- updates existing data, usually <acronym>SQL</acronym>
- <acronym>UPDATE</acronym>.
- </para>
- </listitem>
- <listitem>
- <para>
- <constant>Zend_Db_Profiler::DELETE</constant>: any query that
- deletes existing data, usually <acronym>SQL</acronym>
- <constant>DELETE</constant>.
- </para>
- </listitem>
- <listitem>
- <para>
- <constant>Zend_Db_Profiler::SELECT</constant>: any query that
- retrieves existing data, usually <acronym>SQL</acronym>
- <acronym>SELECT</acronym>.
- </para>
- </listitem>
- <listitem>
- <para>
- <constant>Zend_Db_Profiler::TRANSACTION</constant>: any
- transactional operation, such as start transaction, commit,
- or rollback.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- As with <methodname>setFilterElapsedSecs()</methodname>, you can remove any
- existing filters by passing <constant>NULL</constant> as the sole
- argument.
- </para>
- <programlisting language="php"><![CDATA[
- // profile only SELECT queries
- $profiler->setFilterQueryType(Zend_Db_Profiler::SELECT);
- // profile SELECT, INSERT, and UPDATE queries
- $profiler->setFilterQueryType(Zend_Db_Profiler::SELECT |
- Zend_Db_Profiler::INSERT |
- Zend_Db_Profiler::UPDATE);
- // profile DELETE queries
- $profiler->setFilterQueryType(Zend_Db_Profiler::DELETE);
- // Remove all filters
- $profiler->setFilterQueryType(null);
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.db.profiler.advanced.getbytype">
- <title>Retrieve profiles by query type</title>
- <para>
- Using <methodname>setFilterQueryType()</methodname> can cut down on the
- profiles generated. However, sometimes it can be more useful to
- keep all profiles, but view only those you need at a given
- moment. Another feature of <methodname>getQueryProfiles()</methodname> is
- that it can do this filtering on-the-fly, by passing a query
- type (or logical combination of query types) as its first
- argument; see <link linkend="zend.db.profiler.advanced.filtertype">this
- section</link> for a list of the query type constants.
- </para>
- <programlisting language="php"><![CDATA[
- // Retrieve only SELECT query profiles
- $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT);
- // Retrieve only SELECT, INSERT, and UPDATE query profiles
- $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT |
- Zend_Db_Profiler::INSERT |
- Zend_Db_Profiler::UPDATE);
- // Retrieve DELETE query profiles
- $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::DELETE);
- ]]></programlisting>
- </sect3>
- </sect2>
- <sect2 id="zend.db.profiler.profilers">
- <title>Specialized Profilers</title>
- <para>
- A Specialized Profiler is an object that inherits from
- <classname>Zend_Db_Profiler</classname>. Specialized Profilers treat
- profiling information in specific ways.
- </para>
- <xi:include href="Zend_Db_Profiler-Firebug.xml" />
- </sect2>
- </sect1>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|