performance-database.xml 4.6 KB

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