1 <?xml version="1.0" encoding="UTF-8"?>
3 <sect1 id="performance.database">
4 <title>Zend_Db Performance</title>
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
16 <sect2 id="performance.database.tableMetadata">
17 <title>How can I reduce overhead introduced by Zend_Db_Table for
18 retrieving table metadata?</title>
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.
30 Fortunately, there are techniques for improving the situation.
33 <sect3 id="performance.database.tableMetadata.cache">
34 <title>Use the metadata cache</title>
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.
44 The <link linkend="zend.db.table.metadata.caching"><classname>Zend_Db_Table
45 </classname> documentation includes information on metadata caching</link>.
49 <sect3 id="performance.database.tableMetadata.hardcoding">
50 <title>Hardcode your metadata in the table definition</title>
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.
63 <sect2 id="performance.database.select">
65 SQL generated with Zend_Db_Select s not hitting my indexes; how can I make it better?
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.
74 <sect3 id="performance.database.select.writeyourown">
75 <title>Write your own tuned SQL</title>
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,
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
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>:
98 <programlisting language="php"><![CDATA[
99 // $adapter is the DB adapter. In Zend_Db_Table, retrieve
100 // it using $this->getAdapter().
103 array_walk($values, array($adapter, 'quoteInto'))