Zend_Db_Profiler
Введение
Zend_Db_Profiler может быть включен
для профилирования запросов.
Профили включают в себя запросы, обработанные адаптером, а также
время, затраченное на обработку запроса. Это позволяет исследовать
выполненные запросы без добавления дополнительного отладочного
кода в классы. Расширенное использование также позволяет
разработчикам указывать, профилирование каких запросов
производить.
Включение профилировщика производится либо передачей директивы
конструктору при создании адаптера, либо последующим обращением к
адаптеру для включения.
'host' => '127.0.0.1',
'username' => 'webuser',
'password' => 'xxxxxxxx',
'dbname' => 'test'
'profiler' => true // включение профилировщика;
// для отключения устанавливайте в false
// (значение по умолчанию)
);
$db = Zend_Db::factory('PDO_MYSQL', $params);
// отключение профилировщика:
$db->getProfiler()->setEnabled(false);
// включение профилировщика:
$db->getProfiler()->setEnabled(true);
Значение опции 'profiler ' является гибким. Оно
интерпретируется по-разному в зависимости от его типа. В большинстве
случаев достаточно использовать простое булево значение, но с
помощью других типов можно управлять поведением профилировщика
Аргумент булевого типа включает профилировщик, если имеет значение
TRUE, и выключает его, если имеет значение
FALSE. По умолчанию адаптер использует класс
профилировщика Zend_Db_Profiler .
$params['profiler'] = true;
$db = Zend_Db::factory('PDO_MYSQL', $params);
Передача объекта профилировщика заставляет адаптер использовать его.
Объект должен принадлежать классу Zend_Db_Profiler или
его производному.
$profiler = MyProject_Db_Profiler();
$profiler->setEnabled(true);
$params['profiler'] = $profiler;
$db = Zend_Db::factory('PDO_MYSQL', $params);
Аргумент может быть ассоциативным массивом, содержащим
ключи 'enabled ', 'instance ' и
'class '. Ключи 'enabled ' и
'instance ' соответствуют булевому типу и объекту,
описанным выше. Ключ 'class ' используется для имени
класса профилировщика, который требуется установить. Класс должен
быть Zend_Db_Profiler или его производным. Класс
инстанцируется конструктором без передачи аргументов. Опция
'class ' игнорируется, если установлена опция
'instance '.
$params['profiler'] = array(
'enabled' => true,
'class' => 'MyProject_Db_Profiler'
);
$db = Zend_Db::factory('PDO_MYSQL', $params);
И наконец, аргумент может быть объектом типа
Zend_Config , содержащим свойства, аналогичные ключам
массива, описанного выше. К примеру, файл "config.ini" может
содержать следующие данные:
[main]
db.profiler.class = "MyProject_Db_Profiler"
db.profiler.enabled = true
Эта конфигурация может быть применена так, как показано в коде ниже:
$config = new Zend_Config_Ini('config.ini', 'main');
$params['profiler'] = $config->db->profiler;
$db = Zend_Db::factory('PDO_MYSQL', $params);
Свойство ' instance ' может быть использовано следующим
образом:
$profiler = new MyProject_Db_Profiler();
$profiler->setEnabled(true);
'instance' => $profiler
);
$config = new Zend_Config($configData);
$params['profiler'] = $config;
$db = Zend_Db::factory('PDO_MYSQL', $params);
Использование профилировщика
Извлечение профилировщика производится в любой момент через
метод getProfiler() адаптера:
$profiler = $db->getProfiler();
Он вернет экземпляр класса Zend_Db_Profiler .
С помощью этого экземпляра разработчик может изучать запросы,
используя различные методы:
-
getTotalNumQueries() возвращает общее количество запросов, обработанных профилировщиком.
-
getTotalElapsedSecs() возвращает общее
количество секунд, затраченное на все запросы, обработанные
профилировщиком.
-
getQueryProfiles() возвращает массив всех профилей запросов.
-
getLastQueryProfile() возвращает последний созданный (самый недавний) профиль запроса, безотносительно
того, был ли запрос завершен (если не был завершен, то
конечное время будет равно null).
-
clear() удаляет все профили запросов из
стека.
Возвращаемое getLastQueryProfile() значение и
отдельные элементы getQueryProfiles() являются
объектами Zend_Db_Profiler_Query , которые дают
возможность исследовать запросы по отдельности:
-
getQuery() возвращает SQL-текст запроса. SQL-текст подготовленного оператора с параметрами является текстом в то время, когда запрос подготавливается, поэтому он содержит метки заполнения, а не значения, используемые во время выполнения запроса.
-
getQueryParams() возвращает массив значений
параметров, которые используются во время выполненения
подготовленного запроса. Этот массив включает в себя как
связанные параметры, так и аргументы для метода оператора
execute() . Ключами массива являются позиционные
(начинающиеся с 1) или именованные (строковые) индексы
параметров.
-
getElapsedSecs() возвращает время выполнения
запроса в секундах.
Информация, предоставляемая Zend_Db_Profiler , полезна
для выявления "узких мест" в приложениях и отладки запросов.
Например, чтобы посмотреть, какой запрос выполнялся
последним:
$query = $profiler->getLastQueryProfile();
Возможно, страница генерируется медленно. Используйте профилировщик
для того, чтобы сначала определить общее количество секунд для
всех запросов, затем выполните обход всех запросов, чтобы найти
тот, который выполняется дольше всех:
$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.
// Профилировать только те запросы, которые отнимают не менее 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 в
качестве единственного аргумента.
// профилирование только запросов 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() может производить
такую фильтрацию "на лету", ему передается тип запроса (или
логическая комбинация типов запросов) в качестве первого
аргумента; список констант типов запросов см.
Фильтрация по типу запроса.
// Получение только профилей запросов 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);
Специализированные профилировщики
Специализированный профилировщик - это объект, который наследует от
Zend_Db_Profiler . Специализированные профилировщики
предназначены для специальной обработки данных профилирования.
Profiling with Firebug
Zend_Db_Profiler_Firebug sends profiling infomation to the
» Firebug » Console.
All data is sent via the Zend_Wildfire_Channel_HttpHeaders
component which uses HTTP headers to ensure the page content is not
disturbed. Debugging AJAX requests that require clean
JSON and XML responses is possible with this approach.
Requirements:
Example #1 DB Profiling with Zend_Controller_Front
// In your bootstrap file
$profiler = new Zend_Db_Profiler_Firebug('All DB Queries');
$profiler->setEnabled(true);
// Attach the profiler to your db adapter
$db->setProfiler($profiler);
// Dispatch your front controller
// All DB queries in your model, view and controller
// files will now be profiled and sent to Firebug
Example #2 DB Profiling without Zend_Controller_Front
$profiler = new Zend_Db_Profiler_Firebug('All DB Queries');
$profiler->setEnabled(true);
// Attach the profiler to your db adapter
$db->setProfiler($profiler);
$request = new Zend_Controller_Request_Http();
$response = new Zend_Controller_Response_Http();
$channel = Zend_Wildfire_Channel_HttpHeaders::getInstance();
$channel->setRequest($request);
$channel->setResponse($response);
// Start output buffering
// Now you can run your DB queries to be profiled
// Flush profiling data to browser
$channel->flush();
$response->sendHeaders();
|
|