1 <sect1 id="zend.db.profiler" xmlns:xi="http://www.w3.org/2001/XInclude">
3 <title>Zend_Db_Profiler</title>
5 <sect2 id="zend.db.profiler.introduction">
7 <title>Введение</title>
10 <code>Zend_Db_Profiler</code> может быть включен
11 для профилирования запросов.
12 Профили включают в себя запросы, обработанные адаптером, а также
13 время, затраченное на обработку запроса. Это позволяет исследовать
14 выполненные запросы без добавления дополнительного отладочного
15 кода в классы. Расширенное использование также позволяет
16 разработчикам указывать, профилирование каких запросов
21 Включение профилировщика производится либо передачей директивы
22 конструктору при создании адаптера, либо последующим обращением к
23 адаптеру для включения.
26 <programlisting language="php"><![CDATA[
28 'host' => '127.0.0.1',
29 'username' => 'webuser',
30 'password' => 'xxxxxxxx',
32 'profiler' => true // включение профилировщика;
33 // для отключения устанавливайте в false
34 // (значение по умолчанию)
37 $db = Zend_Db::factory('PDO_MYSQL', $params);
39 // отключение профилировщика:
40 $db->getProfiler()->setEnabled(false);
42 // включение профилировщика:
43 $db->getProfiler()->setEnabled(true);
48 Значение опции '<code>profiler</code>' является гибким. Оно
49 интерпретируется по-разному в зависимости от его типа. В большинстве
50 случаев достаточно использовать простое булево значение, но с
51 помощью других типов можно управлять поведением профилировщика
55 Аргумент булевого типа включает профилировщик, если имеет значение
56 <constant>TRUE</constant>, и выключает его, если имеет значение
57 <constant>FALSE</constant>. По умолчанию адаптер использует класс
58 профилировщика <code>Zend_Db_Profiler</code>.
59 <programlisting language="php"><![CDATA[
60 $params['profiler'] = true;
61 $db = Zend_Db::factory('PDO_MYSQL', $params);
67 Передача объекта профилировщика заставляет адаптер использовать его.
68 Объект должен принадлежать классу <code>Zend_Db_Profiler</code> или
70 <programlisting language="php"><![CDATA[
71 $profiler = MyProject_Db_Profiler();
72 $profiler->setEnabled(true);
73 $params['profiler'] = $profiler;
74 $db = Zend_Db::factory('PDO_MYSQL', $params);
80 Аргумент может быть ассоциативным массивом, содержащим
81 ключи '<code>enabled</code>', '<code>instance</code>' и
82 '<code>class</code>'. Ключи '<code>enabled</code>' и
83 '<code>instance</code>' соответствуют булевому типу и объекту,
84 описанным выше. Ключ '<code>class</code>' используется для имени
85 класса профилировщика, который требуется установить. Класс должен
86 быть <code>Zend_Db_Profiler</code> или его производным. Класс
87 инстанцируется конструктором без передачи аргументов. Опция
88 '<code>class</code>' игнорируется, если установлена опция
89 '<code>instance</code>'.
90 <programlisting language="php"><![CDATA[
91 $params['profiler'] = array(
93 'class' => 'MyProject_Db_Profiler'
95 $db = Zend_Db::factory('PDO_MYSQL', $params);
101 И наконец, аргумент может быть объектом типа
102 <code>Zend_Config</code>, содержащим свойства, аналогичные ключам
103 массива, описанного выше. К примеру, файл "config.ini" может
104 содержать следующие данные:
105 <programlisting language="ini"><![CDATA[
107 db.profiler.class = "MyProject_Db_Profiler"
108 db.profiler.enabled = true
112 Эта конфигурация может быть применена так, как показано в коде ниже:
114 <programlisting language="php"><![CDATA[
115 $config = new Zend_Config_Ini('config.ini', 'main');
116 $params['profiler'] = $config->db->profiler;
117 $db = Zend_Db::factory('PDO_MYSQL', $params);
121 Свойство '<code>instance</code>' может быть использовано следующим
123 <programlisting language="php"><![CDATA[
124 $profiler = new MyProject_Db_Profiler();
125 $profiler->setEnabled(true);
127 'instance' => $profiler
129 $config = new Zend_Config($configData);
130 $params['profiler'] = $config;
131 $db = Zend_Db::factory('PDO_MYSQL', $params);
139 <sect2 id="zend.db.profiler.using">
141 <title>Использование профилировщика</title>
144 Извлечение профилировщика производится в любой момент через
145 метод <code>getProfiler()</code> адаптера:
148 <programlisting language="php"><![CDATA[
149 $profiler = $db->getProfiler();
154 Он вернет экземпляр класса <code>Zend_Db_Profiler</code>.
155 С помощью этого экземпляра разработчик может изучать запросы,
156 используя различные методы:
162 <code>getTotalNumQueries()</code> возвращает общее количество запросов, обработанных профилировщиком.
167 <code>getTotalElapsedSecs()</code> возвращает общее
168 количество секунд, затраченное на все запросы, обработанные
174 <code>getQueryProfiles()</code> возвращает массив всех профилей запросов.
179 <code>getLastQueryProfile()</code> возвращает последний созданный (самый недавний) профиль запроса, безотносительно
180 того, был ли запрос завершен (если не был завершен, то
181 конечное время будет равно null).
186 <code>clear()</code> удаляет все профили запросов из
193 Возвращаемое <code>getLastQueryProfile()</code> значение и
194 отдельные элементы <code>getQueryProfiles()</code> являются
195 объектами <code>Zend_Db_Profiler_Query</code>, которые дают
196 возможность исследовать запросы по отдельности:
202 <code>getQuery()</code> возвращает SQL-текст запроса. SQL-текст подготовленного оператора с параметрами является текстом в то время, когда запрос подготавливается, поэтому он содержит метки заполнения, а не значения, используемые во время выполнения запроса.
207 <code>getQueryParams()</code> возвращает массив значений
208 параметров, которые используются во время выполненения
209 подготовленного запроса. Этот массив включает в себя как
210 связанные параметры, так и аргументы для метода оператора
211 <code>execute()</code>. Ключами массива являются позиционные
212 (начинающиеся с 1) или именованные (строковые) индексы
218 <code>getElapsedSecs()</code> возвращает время выполнения
225 Информация, предоставляемая <code>Zend_Db_Profiler</code>, полезна
226 для выявления "узких мест" в приложениях и отладки запросов.
227 Например, чтобы посмотреть, какой запрос выполнялся
231 <programlisting language="php"><![CDATA[
232 $query = $profiler->getLastQueryProfile();
234 echo $query->getQuery();
239 Возможно, страница генерируется медленно. Используйте профилировщик
240 для того, чтобы сначала определить общее количество секунд для
241 всех запросов, затем выполните обход всех запросов, чтобы найти
242 тот, который выполняется дольше всех:
245 <programlisting language="php"><![CDATA[
246 $totalTime = $profiler->getTotalElapsedSecs();
247 $queryCount = $profiler->getTotalNumQueries();
249 $longestQuery = null;
251 foreach ($profiler->getQueryProfiles() as $query) {
252 if ($query->getElapsedSecs() > $longestTime) {
253 $longestTime = $query->getElapsedSecs();
254 $longestQuery = $query->getQuery();
258 echo 'Executed ' . $queryCount . ' queries in ' . $totalTime .
260 echo 'Average query length: ' . $totalTime / $queryCount .
262 echo 'Queries per second: ' . $queryCount / $totalTime . "\n";
263 echo 'Longest query length: ' . $longestTime . "\n";
264 echo "Longest query: \n" . $longestQuery . "\n";
270 <sect2 id="zend.db.profiler.advanced">
272 <title>Расширенное использование профилировщика</title>
275 Кроме исследования запросов, профилировщик также позволяет
276 фильтровать запросы, для которых
277 создаются профили. Следующие методы работают на экземпляре
278 <code>Zend_Db_Profiler</code>:
281 <sect3 id="zend.db.profiler.advanced.filtertime">
282 <title>Фильтрация по времени выполнения запроса</title>
285 <code>setFilterElapsedSecs()</code> дает возможность
286 разработчику устанавливать минимальное время запроса, после
287 которого будет проводиться профилирование запросов.
288 Для того, чтобы убрать фильтрацию, передайте методу значение
292 <programlisting language="php"><![CDATA[
293 // Профилировать только те запросы, которые отнимают не менее 5 секунд:
294 $profiler->setFilterElapsedSecs(5);
296 // Профилировать все запросы безотносительно времени выполнения:
297 $profiler->setFilterElapsedSecs(null);
302 <sect3 id="zend.db.profiler.advanced.filtertype">
303 <title>Фильтрация по типу запроса</title>
306 <code>setFilterQueryType()</code> дает разработчику возможность
307 указывать, для каких типов запросов должны создаваться профили;
308 для обработки нескольких типов запросов используйте логическое
309 <code>OR</code>. Типы запросов определены в следующих константах
310 <code>Zend_Db_Profiler</code>:
316 <code>Zend_Db_Profiler::CONNECT</code>: операции по
317 установке соединения или выбора базы данных.
322 <code>Zend_Db_Profiler::QUERY</code>: общие запросы к
323 базе данных, которые не соответствуют другим типам.
328 <code>Zend_Db_Profiler::INSERT</code>: любые запросы,
329 через которые добавляются новые данные в базу данных,
330 как правило, это команда INSERT.
335 <code>Zend_Db_Profiler::UPDATE</code>: любые запросы,
336 которые обновляют существующие данные, обычно это
342 <code>Zend_Db_Profiler::DELETE</code>: любые запросы,
343 которые удаляют существующие данные, обычно это команда
349 <code>Zend_Db_Profiler::SELECT</code>: любые запросы,
350 через которые извлекаются существующие данные, обычно
356 <code>Zend_Db_Profiler::TRANSACTION</code>: любые
357 операции с транзакциями, такие, как начало транзакции,
358 фиксация транзакции или откат.
364 Как и в случае <code>setFilterElapsedSecs()</code>, вы можете
365 удалить все фильтры, передав <constant>NULL</constant> в
366 качестве единственного аргумента.
369 <programlisting language="php"><![CDATA[
370 // профилирование только запросов SELECT
371 $profiler->setFilterQueryType(Zend_Db_Profiler::SELECT);
373 // профилирование запросов SELECT, INSERT и UPDATE
374 $profiler->setFilterQueryType(Zend_Db_Profiler::SELECT |
375 Zend_Db_Profiler::INSERT |
376 Zend_Db_Profiler::UPDATE);
378 // профилирование запросов DELETE
379 $profiler->setFilterQueryType(Zend_Db_Profiler::DELETE);
381 // удалить все фильтры
382 $profiler->setFilterQueryType(null);
388 <sect3 id="zend.db.profiler.advanced.getbytype">
389 <title>Получение профилей по типу запроса</title>
392 Использование метода <code>setFilterQueryType()</code> может
393 сократить количество генерируемых профилей. Тем не менее,
394 иногда может быть полезным хранить все профили, но просматривать
395 только те, которые нужны в данный момент. Другой метод
396 <code>getQueryProfiles()</code> может производить
397 такую фильтрацию "на лету", ему передается тип запроса (или
398 логическая комбинация типов запросов) в качестве первого
399 аргумента; список констант типов запросов см.
400 <xref linkend="zend.db.profiler.advanced.filtertype" />.
403 <programlisting language="php"><![CDATA[
404 // Получение только профилей запросов SELECT
405 $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT);
407 // Получение только профилей запросов SELECT, INSERT и UPDATE
408 $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT |
409 Zend_Db_Profiler::INSERT |
410 Zend_Db_Profiler::UPDATE);
412 // Получение профилей запросов DELETE
413 $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::DELETE);
421 <sect2 id="zend.db.profiler.profilers">
422 <title>Специализированные профилировщики</title>
425 Специализированный профилировщик - это объект, который наследует от
426 <code>Zend_Db_Profiler</code>. Специализированные профилировщики
427 предназначены для специальной обработки данных профилирования.
430 <xi:include href="Zend_Db_Profiler-Firebug.xml">
431 <xi:fallback><xi:include href="../../en/module_specs/Zend_Db_Profiler-Firebug.xml" /></xi:fallback>