Pergunta

Estou escrevendo algumas rotinas de banco de dados e usando instruções preparadas.Meu ambiente é DOP com PHP5.

Entendo que as instruções preparadas fornecem principalmente um benefício de desempenho, bem como alguns bônus auxiliares, como não ter que escapar manualmente dos dados de entrada do SQL.

Minha pergunta é sobre a parte de desempenho.

Tenho duas implementações de uma função getPrice abaixo que pega um ID de produto e retorna seu preço.

getPrice_A reutiliza o mesmo objeto PDOStatement em chamadas subsequentes na mesma execução de script.Isso é necessário ou recomendado?Em caso afirmativo, existe alguma maneira de evitar a duplicação desse código extra em cada get*() em cada modelo?

getPrice_B cria um novo objeto PDOStatement em cada chamada.O SGBD reconhecerá que esta declaração já foi preparada e ainda poderá pular algum trabalho?Em outras palavras, esta implementação aproveita adequadamente os benefícios de desempenho das instruções preparadas?

Depois de escrever tudo isso e ler, imagino que getPrice_B está bem e getPrice_A está fornecendo um benefício insignificante além disso, que pode ou não valer a pena a complicação extra.

Eu ainda gostaria de ouvir com certeza de alguém mais experiente.

Assuma isso $pdo é um objeto PDO válido e conectado nos exemplos abaixo.

<?php
class Product {
    static function &getPrice_A($id) {
        static $stmt;
        if (!$stmt) {
            $stmt = $pdo->prepare('SELECT price FROM products WHERE id = ?');
        }
        $stmt->execute(array($id));
        return $stmt->fetchColumn(0);
    }

    static function &getPrice_B($id) {
        $stmt = $pdo->prepare('SELECT price FROM products WHERE id = ?');
        $stmt->execute(array($id));
        return $stmt->fetchColumn(0);
    }
}

// example usage:
$price = Product::getPrice(4982);
echo "Product 4982 costs $price\n";
Foi útil?

Solução

Pelo que entendi, as instruções preparadas reutilizarão o plano SQL gerado se for a mesma instrução, de modo que o banco de dados verá a mesma instrução preparada e não precisará fazer o trabalho para descobrir como consultar o banco de dados.Eu diria que o trabalho extra de salvar a declaração preparada em Product::getPrice_A normalmente não é muito útil, mais porque pode obscurecer o código do que por um problema de desempenho.Ao lidar com desempenho, acho que é sempre melhor focar na clareza do código e depois no desempenho quando você tiver estatísticas reais que indiquem um problema.

Eu diria "sim, o trabalho extra é desnecessário" (independentemente de realmente aumentar o desempenho).Além disso, não sou um grande especialista em banco de dados, mas o ganho de desempenho de instruções preparadas é algo que ouvi de outras pessoas e está no nível do banco de dados, não no nível do código (portanto, se o código estiver realmente invocando uma instrução parametrizada no banco de dados real, então o banco de dados pode fazer o cache do plano de execução ...embora, dependendo do banco de dados, você possa obter o benefício mesmo sem a instrução parametrizada).

De qualquer forma, se você está realmente preocupado (e vendo) problemas de desempenho do banco de dados, você deve procurar uma solução de cache...dos quais eu recomendo fortemente memcached.Com essa solução, você pode armazenar em cache os resultados da sua consulta e nem mesmo acessar o banco de dados para itens que você acessa com frequência.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top