# Zend_Db_Profiler

## Introdução

`Zend_Db_Profiler` pode ser habilitado para permitir o profilling(análise de desempenho) de suas consultas(instruções SQL). Neste profiler(analisador) incluem-se as consultas processadas pelo adaptador e o tempo gasto em suas execuções, permitindo inspecionar as consultas que foram executadas, sem a necessidade de adicionar código ou classes extras de depuração. O seu uso avançado permite também que o desenvolvedor filtre quais consultas serão analisadas.

Habilite o profiler para todos as consultas passando uma directiva para o construtor do adaptador, ou solicitando ao adaptador para habilitá-lo depois.

    <?php
    require_once 'Zend/Db.php';

    $params = array (
        'host'     => '127.0.0.1',
        'username' => 'malory',
        'password' => '******',
        'dbname'   => 'camelot',
        'profiler' => true  // ligando o profiller; mude para false para desabilitá-lo(padrão)
    );

    $db = Zend_Db::factory('PDO_MYSQL', $params);

    // desligando o profiller:
    $db->getProfiler()->setEnabled(false);

    // ligando o profiller:
    $db->getProfiler()->setEnabled(true);

## Usando o Profiler

A qualquer momento, capture o profiler usando o método `getProfiler()` do adaptador.

    <?php
    $profiler = $db->getProfiler();

Com isto, é retornado uma instância do objeto `Zend_Db_Profiler`. Com esta instância, o desenvolvedor pode examinar suas consultas usando uma variedade de métodos:

- `getTotalNumQueries()` retorna o número total de consultas que foram analisadas.

- `getTotalElapsedSecs()` retorna o número total de segundos gastos em todas as consultas analisadas.

- `getQueryProfiles()` retorna um array com todas as análises das consultas.

- `getLastQueryProfile` retorna a última (mais recente) consulta analisada, independente ou não se esta consulta foi finalizada(se não, o tempo final será nulo)

- `clear()` limpa qualquer análise antiga da pilha de execução.

O valor retornado pelo `getLastQueryProfile()` e os elementos individuais do `getQueryProfiles()` são objetos do `Zend_Db_Profiler_Query`, que provê a habilidade de inspecionar suas consultas individualmente:

- `getQuery()` retorna o texto SQL da consulta. O texto SQL de uma instrução preparada (prepared statement) com seus parâmetros é o texto no momento em que a consulta foi preparada, contendo apenas os seus parâmetros, e não os seus valores usados quando a instrução é executada.

- `getQueryParams()` retorna um array de valores dos parâmetros que são usados quando for executada uma query preparada. Nisto incluem-se ambos parâmetros e argumentos acoplados do método `execute()` da instrução. As chaves do array são os posicionais (1-baseado) ou nomeados(string) índices de parâmetro.

- `getElapsedSecs()` retorna o número de segundos que a consulta executou.

A informação fornecida pelo `Zend_Db_Profiler` é útil para analisar os gargalos das aplicações, e para depurar consultas que foram executadas. Por exemplo, para ver a última consulta que foi executada:

    <?php
    $query = $profiler->getLastQueryProfile();

    echo $query->getQuery();

Talvez uma página qualquer esteja gerando lentidão. Use o profiler para determinar primeiro o total de segundos gastos em todas as consultas, e então examine-as para encontrar aquele que demorou mais tempo para executar.

    <?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 'Executado: ' . $queryCount . ' consultas em ' . $totalTime . ' seconds' . "\n";
    echo 'Tamanho médio da query' . $totalTime / $queryCount . ' seconds' . "\n";
    echo 'consultas por segundo: ' . $queryCount / $totalTime . "\n";
    echo 'Query que demorou mais tempo: ' . $longestTime . "\n";
    echo "Query mais longa: \n" . $longestQuery . "\n";

## Uso Avançado do Profiller

Além da inspeção de consultas, o profiler também permite ao devenvolvedor filtrar quais consultas sejam analisadas. Os seguintes métodos operam em uma instância de `Zend_Db_Profiler`.

### Filtro por tempo decorrido das consultas

`setFilterElapsedSecs()` permite ao desenvolvedor setar um tempo mínimo para uma consulta antes de ela ser analisada. Para remover o filtro, passe para o método um valor nulo.

    <?php
    // Apenas consultas analisadas que levam ao menos 5 segundos:
    $profiler->setFilterElapsedSecs(5);

    // Todas as consultas analisadas, não importando o tamanho:
    $profiler->setFilterElapsedSecs(null);

### Filtro pelo tipo de consulta

`setFilterQueryType()` permite ao desenvolvedor setar quais tipos de consultas deverão ser analisadas; para analisar múltiplos tipos, lógicos ou todas. Os tipos de consultas são definidas segundo as constantes de `Zend_Db_Profiler`

- `Zend_Db_Profiler::CONNECT`: operações de conexão, ou seleção de base de dados.

- `Zend_Db_Profiler::QUERY`: consultas gerais da base de dados que não se encaixam com outro tipos.

- `Zend_Db_Profiler::INSERT`: qualquer consulta que adicionar novos dados para a base de dados, geralmente um INSERT SQL.

- `Zend_Db_Profiler::UPDATE`: qualquer consulta que atualiza dados existentes, geralmente um UPDATE SQL.

- `Zend_Db_Profiler::DELETE`: qualquer consulta que exclui dados existentes, geralmente um DELETE SQL.

- `Zend_Db_Profiler::SELECT`: qualquer consulta que retorna dados existentes, geralmente um SELECT SQL.

- `Zend_Db_Profiler::TRANSACTION`: qualquer operação transacional, como a inicialição da transação, commit ou rollback.

Assim como usando o `setFilterElapsedSecs()`, você pode remover quaisquer filtros existentes passando `null` como único argumento.

    <?php
    // Analisa somente consultas usando SELECT
    $profiler->setFilterQueryType(Zend_Db_Profiler::SELECT);

    // Analisa as consultas SELECT, INSERT e UPDATE
    $profiler->setFilterQueryType(Zend_Db_Profiler::SELECT | Zend_Db_Profiler::INSERT | Zend_Db_Profiler::UPDATE);

    // Analisa a instrução DELETE (então podemos descobrir porque os dados continuam desaparecendo)
    $profiler->setFilterQueryType(Zend_Db_Profiler::DELETE);

    // Remove totos os filtros
    $profiler->setFilterQueryType(null);

### Retorna análises por tipo de consulta

Usando o `setFilterQueryType()`, podemos resumir as análises geradas. Entretanto, às vezes é mais útil manter todas as análises e visualizar somente aquelas que você precisa num determinado momento. Outra funcionalidade do `getQueryProfiles()` é a capacidade de fazer esta filtragem "on-the-fly" (execução de código em tempo de execução), passando o tipo da consulta(ou uma combinação lógica de tipos) em seu primeiro argumento; veja na uma lista de todas as constantes dos tipos de consultas.

    <?php
    // Retorna apenas consultas SELECT analisadas
    $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT);

    // Retorna apenas anásiles de consultas SELECT, INSERT e UPDATE.
    $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT | Zend_Db_Profiler::INSERT | Zend_Db_Profiler::UPDATE);

    // Retorna as análises feitas na instrução DELETE (então podemos descobrir porque os dados continuam desaparecendo)
    $profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::DELETE);