Zend_Db_Profiler.xml 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. <sect1 id="zend.db.profiler" xmlns:xi="http://www.w3.org/2001/XInclude">
  2. <title>Zend_Db_Profiler</title>
  3. <sect2 id="zend.db.profiler.introduction">
  4. <title>Введение</title>
  5. <para>
  6. <code>Zend_Db_Profiler</code> может быть включен
  7. для профилирования запросов.
  8. Профили включают в себя запросы, обработанные адаптером, а также
  9. время, затраченное на обработку запроса. Это позволяет исследовать
  10. выполненные запросы без добавления дополнительного отладочного
  11. кода в классы. Расширенное использование также позволяет
  12. разработчикам указывать, профилирование каких запросов
  13. производить.
  14. </para>
  15. <para>
  16. Включение профилировщика производится либо передачей директивы
  17. конструктору при создании адаптера, либо последующим обращением к
  18. адаптеру для включения.
  19. </para>
  20. <programlisting language="php"><![CDATA[
  21. $params = array(
  22. 'host' => '127.0.0.1',
  23. 'username' => 'webuser',
  24. 'password' => 'xxxxxxxx',
  25. 'dbname' => 'test'
  26. 'profiler' => true // включение профилировщика;
  27. // для отключения устанавливайте в false
  28. // (значение по умолчанию)
  29. );
  30. $db = Zend_Db::factory('PDO_MYSQL', $params);
  31. // отключение профилировщика:
  32. $db->getProfiler()->setEnabled(false);
  33. // включение профилировщика:
  34. $db->getProfiler()->setEnabled(true);
  35. ]]>
  36. </programlisting>
  37. <para>
  38. Значение опции '<code>profiler</code>' является гибким. Оно
  39. интерпретируется по-разному в зависимости от его типа. В большинстве
  40. случаев достаточно использовать простое булево значение, но с
  41. помощью других типов можно управлять поведением профилировщика
  42. </para>
  43. <para>
  44. Аргумент булевого типа включает профилировщик, если имеет значение
  45. <constant>TRUE</constant>, и выключает его, если имеет значение
  46. <constant>FALSE</constant>. По умолчанию адаптер использует класс
  47. профилировщика <code>Zend_Db_Profiler</code>.
  48. <programlisting language="php"><![CDATA[
  49. $params['profiler'] = true;
  50. $db = Zend_Db::factory('PDO_MYSQL', $params);
  51. ]]>
  52. </programlisting>
  53. </para>
  54. <para>
  55. Передача объекта профилировщика заставляет адаптер использовать его.
  56. Объект должен принадлежать классу <code>Zend_Db_Profiler</code> или
  57. его производному.
  58. <programlisting language="php"><![CDATA[
  59. $profiler = MyProject_Db_Profiler();
  60. $profiler->setEnabled(true);
  61. $params['profiler'] = $profiler;
  62. $db = Zend_Db::factory('PDO_MYSQL', $params);
  63. ]]>
  64. </programlisting>
  65. </para>
  66. <para>
  67. Аргумент может быть ассоциативным массивом, содержащим
  68. ключи '<code>enabled</code>', '<code>instance</code>' и
  69. '<code>class</code>'. Ключи '<code>enabled</code>' и
  70. '<code>instance</code>' соответствуют булевому типу и объекту,
  71. описанным выше. Ключ '<code>class</code>' используется для имени
  72. класса профилировщика, который требуется установить. Класс должен
  73. быть <code>Zend_Db_Profiler</code> или его производным. Класс
  74. инстанцируется конструктором без передачи аргументов. Опция
  75. '<code>class</code>' игнорируется, если установлена опция
  76. '<code>instance</code>'.
  77. <programlisting language="php"><![CDATA[
  78. $params['profiler'] = array(
  79. 'enabled' => true,
  80. 'class' => 'MyProject_Db_Profiler'
  81. );
  82. $db = Zend_Db::factory('PDO_MYSQL', $params);
  83. ]]>
  84. </programlisting>
  85. </para>
  86. <para>
  87. И наконец, аргумент может быть объектом типа
  88. <code>Zend_Config</code>, содержащим свойства, аналогичные ключам
  89. массива, описанного выше. К примеру, файл "config.ini" может
  90. содержать следующие данные:
  91. <programlisting language="ini"><![CDATA[
  92. [main]
  93. db.profiler.class = "MyProject_Db_Profiler"
  94. db.profiler.enabled = true
  95. ]]>
  96. </programlisting>
  97. Эта конфигурация может быть применена так, как показано в коде ниже:
  98. <programlisting language="php"><![CDATA[
  99. $config = new Zend_Config_Ini('config.ini', 'main');
  100. $params['profiler'] = $config->db->profiler;
  101. $db = Zend_Db::factory('PDO_MYSQL', $params);
  102. ]]>
  103. </programlisting>
  104. Свойство '<code>instance</code>' может быть использовано следующим
  105. образом:
  106. <programlisting language="php"><![CDATA[
  107. $profiler = new MyProject_Db_Profiler();
  108. $profiler->setEnabled(true);
  109. $configData = array(
  110. 'instance' => $profiler
  111. );
  112. $config = new Zend_Config($configData);
  113. $params['profiler'] = $config;
  114. $db = Zend_Db::factory('PDO_MYSQL', $params);
  115. ]]>
  116. </programlisting>
  117. </para>
  118. </sect2>
  119. <sect2 id="zend.db.profiler.using">
  120. <title>Использование профилировщика</title>
  121. <para>
  122. Извлечение профилировщика производится в любой момент через
  123. метод <code>getProfiler()</code> адаптера:
  124. </para>
  125. <programlisting language="php"><![CDATA[
  126. $profiler = $db->getProfiler();
  127. ]]>
  128. </programlisting>
  129. <para>
  130. Он вернет экземпляр класса <code>Zend_Db_Profiler</code>.
  131. С помощью этого экземпляра разработчик может изучать запросы,
  132. используя различные методы:
  133. </para>
  134. <itemizedlist>
  135. <listitem>
  136. <para>
  137. <code>getTotalNumQueries()</code> возвращает общее количество запросов, обработанных профилировщиком.
  138. </para>
  139. </listitem>
  140. <listitem>
  141. <para>
  142. <code>getTotalElapsedSecs()</code> возвращает общее
  143. количество секунд, затраченное на все запросы, обработанные
  144. профилировщиком.
  145. </para>
  146. </listitem>
  147. <listitem>
  148. <para>
  149. <code>getQueryProfiles()</code> возвращает массив всех профилей запросов.
  150. </para>
  151. </listitem>
  152. <listitem>
  153. <para>
  154. <code>getLastQueryProfile()</code> возвращает последний созданный (самый недавний) профиль запроса, безотносительно
  155. того, был ли запрос завершен (если не был завершен, то
  156. конечное время будет равно null).
  157. </para>
  158. </listitem>
  159. <listitem>
  160. <para>
  161. <code>clear()</code> удаляет все профили запросов из
  162. стека.
  163. </para>
  164. </listitem>
  165. </itemizedlist>
  166. <para>
  167. Возвращаемое <code>getLastQueryProfile()</code> значение и
  168. отдельные элементы <code>getQueryProfiles()</code> являются
  169. объектами <code>Zend_Db_Profiler_Query</code>, которые дают
  170. возможность исследовать запросы по отдельности:
  171. </para>
  172. <itemizedlist>
  173. <listitem>
  174. <para>
  175. <code>getQuery()</code> возвращает SQL-текст запроса. SQL-текст подготовленного оператора с параметрами является текстом в то время, когда запрос подготавливается, поэтому он содержит метки заполнения, а не значения, используемые во время выполнения запроса.
  176. </para>
  177. </listitem>
  178. <listitem>
  179. <para>
  180. <code>getQueryParams()</code> возвращает массив значений
  181. параметров, которые используются во время выполненения
  182. подготовленного запроса. Этот массив включает в себя как
  183. связанные параметры, так и аргументы для метода оператора
  184. <code>execute()</code>. Ключами массива являются позиционные
  185. (начинающиеся с 1) или именованные (строковые) индексы
  186. параметров.
  187. </para>
  188. </listitem>
  189. <listitem>
  190. <para>
  191. <code>getElapsedSecs()</code> возвращает время выполнения
  192. запроса в секундах.
  193. </para>
  194. </listitem>
  195. </itemizedlist>
  196. <para>
  197. Информация, предоставляемая <code>Zend_Db_Profiler</code>, полезна
  198. для выявления "узких мест" в приложениях и отладки запросов.
  199. Например, чтобы посмотреть, какой запрос выполнялся
  200. последним:
  201. </para>
  202. <programlisting language="php"><![CDATA[
  203. $query = $profiler->getLastQueryProfile();
  204. echo $query->getQuery();
  205. ]]>
  206. </programlisting>
  207. <para>
  208. Возможно, страница генерируется медленно. Используйте профилировщик
  209. для того, чтобы сначала определить общее количество секунд для
  210. всех запросов, затем выполните обход всех запросов, чтобы найти
  211. тот, который выполняется дольше всех:
  212. </para>
  213. <programlisting language="php"><![CDATA[
  214. $totalTime = $profiler->getTotalElapsedSecs();
  215. $queryCount = $profiler->getTotalNumQueries();
  216. $longestTime = 0;
  217. $longestQuery = null;
  218. foreach ($profiler->getQueryProfiles() as $query) {
  219. if ($query->getElapsedSecs() > $longestTime) {
  220. $longestTime = $query->getElapsedSecs();
  221. $longestQuery = $query->getQuery();
  222. }
  223. }
  224. echo 'Executed ' . $queryCount . ' queries in ' . $totalTime .
  225. ' seconds' . "\n";
  226. echo 'Average query length: ' . $totalTime / $queryCount .
  227. ' seconds' . "\n";
  228. echo 'Queries per second: ' . $queryCount / $totalTime . "\n";
  229. echo 'Longest query length: ' . $longestTime . "\n";
  230. echo "Longest query: \n" . $longestQuery . "\n";
  231. ]]>
  232. </programlisting>
  233. </sect2>
  234. <sect2 id="zend.db.profiler.advanced">
  235. <title>Расширенное использование профилировщика</title>
  236. <para>
  237. Кроме исследования запросов, профилировщик также позволяет
  238. фильтровать запросы, для которых
  239. создаются профили. Следующие методы работают на экземпляре
  240. <code>Zend_Db_Profiler</code>:
  241. </para>
  242. <sect3 id="zend.db.profiler.advanced.filtertime">
  243. <title>Фильтрация по времени выполнения запроса</title>
  244. <para>
  245. <code>setFilterElapsedSecs()</code> дает возможность
  246. разработчику устанавливать минимальное время запроса, после
  247. которого будет проводиться профилирование запросов.
  248. Для того, чтобы убрать фильтрацию, передайте методу значение
  249. null.
  250. </para>
  251. <programlisting language="php"><![CDATA[
  252. // Профилировать только те запросы, которые отнимают не менее 5 секунд:
  253. $profiler->setFilterElapsedSecs(5);
  254. // Профилировать все запросы безотносительно времени выполнения:
  255. $profiler->setFilterElapsedSecs(null);
  256. ]]>
  257. </programlisting>
  258. </sect3>
  259. <sect3 id="zend.db.profiler.advanced.filtertype">
  260. <title>Фильтрация по типу запроса</title>
  261. <para>
  262. <code>setFilterQueryType()</code> дает разработчику возможность
  263. указывать, для каких типов запросов должны создаваться профили;
  264. для обработки нескольких типов запросов используйте логическое
  265. <code>OR</code>. Типы запросов определены в следующих константах
  266. <code>Zend_Db_Profiler</code>:
  267. </para>
  268. <itemizedlist>
  269. <listitem>
  270. <para>
  271. <code>Zend_Db_Profiler::CONNECT</code>: операции по
  272. установке соединения или выбора базы данных.
  273. </para>
  274. </listitem>
  275. <listitem>
  276. <para>
  277. <code>Zend_Db_Profiler::QUERY</code>: общие запросы к
  278. базе данных, которые не соответствуют другим типам.
  279. </para>
  280. </listitem>
  281. <listitem>
  282. <para>
  283. <code>Zend_Db_Profiler::INSERT</code>: любые запросы,
  284. через которые добавляются новые данные в базу данных,
  285. как правило, это команда INSERT.
  286. </para>
  287. </listitem>
  288. <listitem>
  289. <para>
  290. <code>Zend_Db_Profiler::UPDATE</code>: любые запросы,
  291. которые обновляют существующие данные, обычно это
  292. команда UPDATE.
  293. </para>
  294. </listitem>
  295. <listitem>
  296. <para>
  297. <code>Zend_Db_Profiler::DELETE</code>: любые запросы,
  298. которые удаляют существующие данные, обычно это команда
  299. DELETE.
  300. </para>
  301. </listitem>
  302. <listitem>
  303. <para>
  304. <code>Zend_Db_Profiler::SELECT</code>: любые запросы,
  305. через которые извлекаются существующие данные, обычно
  306. это команда SELECT.
  307. </para>
  308. </listitem>
  309. <listitem>
  310. <para>
  311. <code>Zend_Db_Profiler::TRANSACTION</code>: любые
  312. операции с транзакциями, такие, как начало транзакции,
  313. фиксация транзакции или откат.
  314. </para>
  315. </listitem>
  316. </itemizedlist>
  317. <para>
  318. Как и в случае <code>setFilterElapsedSecs()</code>, вы можете
  319. удалить все фильтры, передав <constant>NULL</constant> в
  320. качестве единственного аргумента.
  321. </para>
  322. <programlisting language="php"><![CDATA[
  323. // профилирование только запросов SELECT
  324. $profiler->setFilterQueryType(Zend_Db_Profiler::SELECT);
  325. // профилирование запросов SELECT, INSERT и UPDATE
  326. $profiler->setFilterQueryType(Zend_Db_Profiler::SELECT |
  327. Zend_Db_Profiler::INSERT |
  328. Zend_Db_Profiler::UPDATE);
  329. // профилирование запросов DELETE
  330. $profiler->setFilterQueryType(Zend_Db_Profiler::DELETE);
  331. // удалить все фильтры
  332. $profiler->setFilterQueryType(null);
  333. ]]>
  334. </programlisting>
  335. </sect3>
  336. <sect3 id="zend.db.profiler.advanced.getbytype">
  337. <title>Получение профилей по типу запроса</title>
  338. <para>
  339. Использование метода <code>setFilterQueryType()</code> может
  340. сократить количество генерируемых профилей. Тем не менее,
  341. иногда может быть полезным хранить все профили, но просматривать
  342. только те, которые нужны в данный момент. Другой метод
  343. <code>getQueryProfiles()</code> может производить
  344. такую фильтрацию "на лету", ему передается тип запроса (или
  345. логическая комбинация типов запросов) в качестве первого
  346. аргумента; список констант типов запросов см.
  347. <xref linkend="zend.db.profiler.advanced.filtertype" />.
  348. </para>
  349. <programlisting language="php"><![CDATA[
  350. // Получение только профилей запросов SELECT
  351. $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT);
  352. // Получение только профилей запросов SELECT, INSERT и UPDATE
  353. $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT |
  354. Zend_Db_Profiler::INSERT |
  355. Zend_Db_Profiler::UPDATE);
  356. // Получение профилей запросов DELETE
  357. $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::DELETE);
  358. ]]>
  359. </programlisting>
  360. </sect3>
  361. </sect2>
  362. <sect2 id="zend.db.profiler.profilers">
  363. <title>Специализированные профилировщики</title>
  364. <para>
  365. Специализированный профилировщик - это объект, который наследует от
  366. <code>Zend_Db_Profiler</code>. Специализированные профилировщики
  367. предназначены для специальной обработки данных профилирования.
  368. </para>
  369. <xi:include href="Zend_Db_Profiler-Firebug.xml">
  370. <xi:fallback><xi:include href="../../en/module_specs/Zend_Db_Profiler-Firebug.xml" /></xi:fallback>
  371. </xi:include>
  372. </sect2>
  373. </sect1>
  374. <!--
  375. vim:se ts=4 sw=4 et:
  376. -->