[ZF-10089] Zend_Log
[zend.git] / documentation / manual / en / ref / performance-database.xml
blobaa30db7be845d8bd7b54b46bae4581a1876a0ecd
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <sect1 id="performance.database">
4     <title>Zend_Db Performance</title>
6     <para>
7         <classname>Zend_Db</classname> is a database abstraction layer, and is intended to
8         provide a common <acronym>API</acronym> for <acronym>SQL</acronym> operations.
9         <classname>Zend_Db_Table</classname> is a
10         Table Data Gateway, intended to abstract common table-level database
11         operations. Due to their abstract nature and the "magic" they do under
12         the hood to perform their operations, they can sometimes introduce
13         performance overhead.
14     </para>
16     <sect2 id="performance.database.tableMetadata">
17         <title>How can I reduce overhead introduced by Zend_Db_Table for
18             retrieving table metadata?</title>
20         <para>
21             In order to keep usage as simple as possible, and also to support
22             constantly changing schemas during development,
23             <classname>Zend_Db_Table</classname> does some magic under the hood: on
24             first use, it fetches the table schema and stores it within object
25             members. This operation is typically expensive, regardless of the
26             database -- which can contribute to bottlenecks in production.
27         </para>
29         <para>
30             Fortunately, there are techniques for improving the situation.
31         </para>
33         <sect3 id="performance.database.tableMetadata.cache">
34             <title>Use the metadata cache</title>
36             <para>
37                 <classname>Zend_Db_Table</classname> can optionally utilize
38                 <classname>Zend_Cache</classname> to cache table metadata. This is
39                 typically faster to access and less expensive than fetching the
40                 metadata from the database itself.
41             </para>
43             <para>
44                 The <link linkend="zend.db.table.metadata.caching"><classname>Zend_Db_Table
45                 </classname> documentation includes information on metadata caching</link>.
46             </para>
47         </sect3>
49         <sect3 id="performance.database.tableMetadata.hardcoding">
50             <title>Hardcode your metadata in the table definition</title>
52             <para>
53                 As of 1.7.0, <classname>Zend_Db_Table</classname> also provides <link
54                     linkend="zend.db.table.metadata.caching.hardcoding">support
55                 for hardcoding metadata in the table definition</link>. This is
56                 an advanced use case, and should only be used when you know the
57                 table schema is unlikely to change, or that you're able to keep
58                 the definitions up-to-date.
59             </para>
60         </sect3>
61     </sect2>
63     <sect2 id="performance.database.select">
64         <title>
65             SQL generated with Zend_Db_Select s not hitting my indexes; how can I make it better?
66         </title>
68         <para>
69             <classname>Zend_Db_Select</classname> is relatively good at its job. However,
70             if you are performing complex queries requiring joins or
71             sub-selects, it can often be fairly naive.
72         </para>
74         <sect3 id="performance.database.select.writeyourown">
75             <title>Write your own tuned SQL</title>
77             <para>
78                 The only real answer is to write your own <acronym>SQL</acronym>;
79                 <classname>Zend_Db</classname> does not require the usage of
80                 <classname>Zend_Db_Select</classname>, so providing your own, tuned
81                 <acronym>SQL</acronym> select statements is a perfectly legitimate approach,
82             </para>
84             <para>
85                 Run <constant>EXPLAIN</constant> on your queries, and test a variety of
86                 approaches until you can reliably hit your indices in the most
87                 performant way -- and then hardcode the <acronym>SQL</acronym> as a class property
88                 or constant.
89             </para>
91             <para>
92                 If the <acronym>SQL</acronym> requires variable arguments, provide placeholders in
93                 the <acronym>SQL</acronym>, and utilize a combination of
94                 <methodname>vsprintf()</methodname> and <methodname>array_walk()</methodname> to
95                 inject the values into the <acronym>SQL</acronym>:
96             </para>
98             <programlisting language="php"><![CDATA[
99 // $adapter is the DB adapter. In Zend_Db_Table, retrieve
100 // it using $this->getAdapter().
101 $sql = vsprintf(
102     self::SELECT_FOO,
103     array_walk($values, array($adapter, 'quoteInto'))
105 ]]></programlisting>
106         </sect3>
107     </sect2>
108 </sect1>
109 <!--
110 vim:se ts=4 sw=4 et: