Zend_Db_Profiler
может быть включен
для того, чтобы сделать возможным профайлинг запросов.
Профaйлы включают в себя запросы, обработанные адаптером, а также
время, затраченное на обработку запроса. Это позволяет исследовать
выполненные запросы без добавления дополнительного отладочного
кода в классы. Расширенное использование также позволяет
разработчикам указывать, для каких запросов создавать профайлы.
Включение профайлера производится либо передачей директивы конструктору адаптера, либо более поздним обращением к адаптеру для включения.
<?php require_once 'Zend/Db.php'; $params = array ( 'host' => '127.0.0.1', 'username' => 'malory', 'password' => '******', 'dbname' => 'camelot', 'profiler' => true // включение профайлера; // для отключения используется false (значение по умолчанию) ); $db = Zend_Db::factory('PDO_MYSQL', $params); // отключение профайлера: $db->getProfiler()->setEnabled(false); // включение профайлера: $db->getProfiler()->setEnabled(true); ?>
Получение профайлера производится в любой момент с помощью
метода getProfiler()
в адаптере БД:
<?php $profiler = $db->getProfiler(); ?>
Это вернет экземпляр класса Zend_Db_Profiler
.
С помощью этого экземпляра разработчик может изучать запросы,
используя различные методы:
getTotalNumQueries()
возвращает общее количество
запросов, которые были обработаны профайлером.
getTotalElapsedSecs()
возвращает общее
количество секунд, затраченное на все запросы, обработанные
профайлером.
getQueryProfiles()
возвращает массив всех профайлов
запросов.
getLastQueryProfile()
возвращает последний
(самый недавний) профайл запроса, безотносительно того, был ли
запрос завершен (Если не был завершен, то конечное время будет
равно NULL
).
clear()
удаляет все профайлы прошлых запросов из
стека.
Возвращаемое getLastQueryProfile()
значение и
отдельные элементы getQueryProfiles()
являются объектами
Zend_Db_Profiler_Query
, которые дают возможность
исследовать отдельные запросы:
getQuery()
возвращает код SQL-запроса.
getElapsedSecs()
возвращает время выполнения запроса
в секундах.
Информация, предоставляемая Zend_Db_Profiler
, полезна
для выявления "узких мест" в приложениях и отладки запросов.
Например, чтобы посмотреть, какой запрос выполнялся
последним:
<?php $query = $profiler->getLastQueryProfile(); echo $query->getQuery(); ?>
Возможно, страница генерируется медленно. Используйте профайлер для того, чтобя сначала определить общее количество секунд для всех запросов, затем выполните обход всех запросов, чтобы найти тот, который выполняется дольше всех:
<?php $totalTime = $profiler->getTotalElapsedSecs(); $queryCount = $profiler->getTotalNumQueries(); $longestTime = 0; $longestQuery = null; foreach ($profiler->getQueryProfiles() as $query) { if ($query->getElapsedSecs() > $longestTime) { $longestTime = $query->getElapsedSecs(); $longestQuery = $query->getQuery(); } } echo 'Executed ' . $queryCount . ' queries in ' . $totalTime . ' seconds' . "\n"; echo 'Average query length: ' . $totalTime / $queryCount . ' seconds' . "\n"; echo 'Queries per second: ' . $queryCount / $totalTime . "\n"; echo 'Longest query length: ' . $longestTime . "\n"; echo "Longest query: \n" . $longestQuery . "\n"; ?>
Кроме исследования запросов, профайлер также дает
возможность разработчику фильтровать запросы, для которых
создаются профайлы. Следующие методы работают на экземпляре
Zend_Db_Profiler
:
setFilterElapsedSecs()
дает возможность
разработчику устанавливать минимальное время запроса, после
которого будет проводиться профайлиг запросов.
Для того, чтобы убрать фильтрацию, передайте методу значение
NULL
.
<?php // Проводить профайлинг только тех запросы, которые отнимают по меньшей мере 5 секунд: $profiler->setFilterElapsedSecs(5); // Профайлировать все запросы безотносительно времени выполнения: $profiler->setFilterElapsedSecs(null); ?>
setFilterQueryType()
дает разработчику возможность
указывать, для каких типов запросов должны создаваться профайлы;
для обработки нескольких типов запросов используйте логическое
OR
. Типы запросов определены в следующих константах
Zend_Db_Profiler
:
Zend_Db_Profiler::CONNECT
: операции по установке
соединения или выбора базы данных.
Zend_Db_Profiler::QUERY
: обычные запросы к
базе данных, которые не подходят к другим типам.
Zend_Db_Profiler::INSERT
: любые запросы, которые
добавляют новые данные в базу данных; как правило,
это команда INSERT.
Zend_Db_Profiler::UPDATE
: любые запросы,
которые обновляют существующие данные, обычно это команда
UPDATE.
Zend_Db_Profiler::DELETE
: любые запросы,
которые удаляют существующие данные, обычно это команда
DELETE.
Zend_Db_Profiler::SELECT
: любые запросы, которые
извлекают существующие данные, обычно это команда SELECT.
Zend_Db_Profiler::TRANSACTION
: любые
операции с транзакциями, такие, как начало транзакции,
фиксация транзакции или откат.
Как и в случае setFilterElapsedSecs()
, вы можете
удалить все фильтры посредством передачи NULL
в
качестве единственного аргумента.
<?php // профайлинг только запросов SELECT $profiler->setFilterQueryType(Zend_Db_Profiler::SELECT); // профайлинг запросов SELECT, INSERT и UPDATE $profiler->setFilterQueryType(Zend_Db_Profiler::SELECT | Zend_Db_Profiler::INSERT | Zend_Db_Profiler::UPDATE); // профайлинг запросов DELETE (так мы можем определить, почему удаляются данные) $profiler->setFilterQueryType(Zend_Db_Profiler::DELETE); // удалить все фильтры $profiler->setFilterQueryType(null); ?>
Использование setFilterQueryType()
может
сократить количество генерируемых профайлов. Тем не менее,
иногда может быть полезным хранить все профайлы, но просматривать
только те, которые нужны в данный момент. Другой метод
getQueryProfiles()
— это то, что может делать такую
фильтрацию "на лету", ему передается тип запроса (или
логическая комбинация типов запросов) в качестве его первого
аргумента; список констант типов запросов см.
Раздел 9.2.3.2, «Фильтрация по типу запроса».
<?php // Получение только профайлов запросов SELECT $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT); // Получение только профайлов запросов SELECT, INSERT и UPDATE $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT | Zend_Db_Profiler::INSERT | Zend_Db_Profiler::UPDATE); // Получение профайлов запросов DELETE (так мы можем определить, почему удаляются данные) $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::DELETE); ?>