Zend_Db_Profiler
może być włączony aby pozwolić na
profilowanie zapytań. Profilowanie umożliwia zbadanie czasu trwania
zapytań pozwalając na inspekcję przeprowadzonych zapytań bez potrzeby
dodawania dodatkowego kodu do klas. Zaawansowane użycie pozwala także
programiście decydować o tym, jakich typów zapytania mają być profilowane.
Włącz profiler przekazując odpowiednią dyrektywę do konstruktora adaptera, lub wywołując później metodę adaptera.
<?php require_once 'Zend/Db.php'; $params = array ( 'host' => '127.0.0.1', 'username' => 'malory', 'password' => '******', 'dbname' => 'camelot', 'profiler' => true // włącz profiler; ustaw false aby wyłączyć (domyślne) ); $db = Zend_Db::factory('PDO_MYSQL', $params); // wyłącz profiler: $db->getProfiler()->setEnabled(false); // włącz profiler: $db->getProfiler()->setEnabled(true); ?>
W dowolnym momencie możesz pobrać profiler używając metody
adaptera getProfiler()
:
<?php $profiler = $db->getProfiler(); ?>
Zwraca to instancję Zend_Db_Profiler
. Używając tej
instancji programista może zbadać zapytania używając rozmaitych
metod:
getTotalNumQueries()
zwraca liczbę wszystkich
zapytań które były profilowane.
getTotalElapsedSecs()
zwraca całkowity czas
trwania profilowanych zapytań.
getQueryProfiles()
zwraca tablicę wszystkich
profilów zapytań.
getLastQueryProfile()
zwraca ostatni (najnowszy)
profil zapytania, niezależnie od tego czy zostało ono zakończone czy
nie (jeśli nie zostało, to czas zakończenia będzie miał wartość null)
clear()
czyści wszystkie poprzednie profile
zapytań ze stosu.
Wartość zwracana przez getLastQueryProfile()
oraz
pojedyncze elementy tablicy zwracanej przez getQueryProfiles()
są obiektami Zend_Db_Profiler_Query
, które dają możliwość
sprawdzenia osobno każdego zapytania.
getQuery()
zwraca tekst SQL zapytania.
getElapsedSecs()
zwraca czas trwania zapytania
Informacja której dostarcza Zend_Db_Profiler
jest
użyteczna przy profilowaniu wąskich gardeł w aplikacjach oraz
do szukania błędów w wykonanych zapytaniach. Na przykład aby
zobaczyć ostatnie zapytanie jakie było wykonane:
<?php $query = $profiler->getLastQueryProfile(); echo $query->getQuery(); ?>
Możliwe, że strona generuje się powoli; użyj profilera aby ustalić czas wykonania wszystkich zapytań, a następnie przejść poprzez zapytania aby znaleść te, które trwało najdłużej:
<?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 'Wykonano ' . $queryCount . ' zapytań w czasie ' . $totalTime . ' sekund' . "\n"; echo 'Średni czas trwania zapytania: ' . $totalTime / $queryCount . ' sekund' . "\n"; echo 'Zapytań na sekundę:: ' . $queryCount / $totalTime . "\n"; echo 'Czas trwania najdłuższego zapytania: ' . $longestTime . "\n"; echo "Najdłuższe zapytanie: \n" . $longestQuery . "\n"; ?>
Oprócz sprawdzania zapytań, profiler pozwala także programiście na
określenie typów zapytań które mają być profilowane. Poniższe
metody operują na instancji Zend_Db_Profiler
:
setFilterElapsedSecs()
pozwala programiście ustalić
minimalny czas trwania zapytania jaki jest potrzebny do tego by
zostało ono profilowane. Aby usunąć filtr, wywołaj metodę z
wartością null w parametrze.
<?php // Profiluj tylko zapytania które trwają przynajmniej 5 sekund: $profiler->setFilterElapsedSecs(5); // Profiluj wszystkie zapytania, niezależnie od czasu ich trwania: $profiler->setFilterElapsedSecs(null); ?>
setFilterQueryType()
pozwala programiście określić,
które typy zapytań powinny być profilowane; aby profilować
zapytania wielu typów użyj logicznego operatora OR. Typy zapytań
są zdefiniowane jako stałe w Zend_Db_Profiler
:
Zend_Db_Profiler::CONNECT
: operacje
połączenia lub wybierania bazy danych.
Zend_Db_Profiler::QUERY
: ogólne zapytania
które nie pasują do pozostałych typów.
Zend_Db_Profiler::INSERT
: każde zapytanie
które wstawia nowe dane do bazy, generalnie SQL INSERT.
Zend_Db_Profiler::UPDATE
: każde zapytanie
ktore uaktualnia dane w bazie, najczęściej SQL UPDATE.
Zend_Db_Profiler::DELETE
: każde zapytanie
które usuwa istnięjące dane, najczęściej SQL DELETE.
Zend_Db_Profiler::SELECT
: każde zapytanie
które pobiera istnięjące dane, najczęściej SQL SELECT.
Zend_Db_Profiler::TRANSACTION
: każda
operacja transakcyjna, taka jak start transakcji, potwierdzenie
zmian czy ich cofnięcie.
Analogicznie jak w metodzie setFilterElapsedSecs()
,
możesz usunąć wszystkie istniejące filtry przekazując metodzie
pusty parametr null
.
<?php // profiluj tylko zapytania SELECT $profiler->setFilterQueryType(Zend_Db_Profiler::SELECT); // profiluj zapytania SELECT, INSERT, oraz UPDATE $profiler->setFilterQueryType(Zend_Db_Profiler::SELECT | Zend_Db_Profiler::INSERT | Zend_Db_Profiler::UPDATE); // profiluj zapytania DELETE $profiler->setFilterQueryType(Zend_Db_Profiler::DELETE); // Usuń wszystkie filtry $profiler->setFilterQueryType(null); ?>
Użycie metody setFilterQueryType()
może zmniejszyć
ilość wygenerowanych profili. Jakkolwiek, czasem bardziej użyteczne
jest przechowywanie wszystkich profili i wyświetlanie tylko
tych których potrzebujesz w danym momencie. Inną funkcjonalnością
metody getQueryProfiles()
jest to, że może ona
przeprowadzić te filtrowanie w locie, po przekazaniu typu
zapytań (lub logicznej kombinacji typów zapytań) jako pierwszego
argumentu; przejdź do Sekcja 9.2.3.2, „Filtrowanie ze względu na typ zapytania”
aby zobaczyć listę stałych określających typy zapytań.
<?php // Pobierz jedynie profile zapytań SELECT $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT); // Pobierz jedynie profile zapytań SELECT, INSERT, oraz UPDATE $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT | Zend_Db_Profiler::INSERT | Zend_Db_Profiler::UPDATE); // Pobierz jedynie profile zapytań DELETE $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::DELETE); ?>