Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

instrução prepare do driver golang sql


As diferenças podem ser sutis, às vezes importantes e às vezes efetivamente inexistentes.

Em geral, uma instrução preparada 1. é preparada com o servidor (SQL analisado, plano de execução gerado etc.), 2. é executado com os parâmetros adicionais e 3. é fechado. Ele permite que você reutilize o mesmo SQL com diferentes parâmetros passados ​​em cada vez, pode ajudar a proteger contra injeção de SQL, pode fornecer algumas melhorias de desempenho (driver/protocolo específico, YMMV) e evitar etapas repetidas, como na geração do plano de execução e análise de SQL em o preparar passo acima.

Para alguém escrevendo código-fonte, uma instrução preparada pode ser mais conveniente do que concatenar strings e enviá-las ao servidor de banco de dados.

O DB.Query() O método recebe SQL como uma string e zero ou mais argumentos (assim como Exec() , ou QueryRow() ). Uma string SQL sem argumentos adicionais consultará exatamente o que você escreveu. No entanto, desde uma string SQL com espaços reservados e argumentos adicionais, uma instrução preparada está sendo feita para você nos bastidores.

O DB.Prepare() explicitamente executa uma instrução preparada, para a qual você passa argumentos, como em:stmt.Exec(...args) .

Há algumas coisas que vale a pena pensar, em termos das diferenças entre os dois e por que usar um ou outro.

Você pode usar DB.Query() sem argumentos. Isso pode ser muito eficiente, pois pode ignorar o preparar --> executar --> fechar seqüência pela qual a instrução preparada necessariamente passa.

Você também pode usá-lo com argumentos adicionais e espaços reservados na string de consulta, e ele executará uma instrução preparada nos bastidores, como mencionei acima. O problema potencial aqui é que, quando você está fazendo várias consultas, cada uma delas resulta em uma declaração preparada sob o capô. Como há etapas extras envolvidas, isso pode ser bastante ineficiente, pois re-prepara, executa e fecha cada vez que você faz essa consulta.

Com uma instrução preparada explícita, você pode evitar essa ineficiência ao tentar reutilizar o SQL que preparou anteriormente, com argumentos potencialmente diferentes.

Mas isso nem sempre funciona como você poderia esperar... Por causa do pool de conexão subjacente que é gerenciado por db/sql, sua "conexão de banco de dados" é bastante virtual. O DB.Prepare() O método preparará a instrução em relação a uma conexão específica e, em seguida, tentará obter essa mesma conexão de volta quando for a hora de executar, mas se essa conexão não estiver disponível, ele simplesmente pegará uma que estiver disponível e preparará novamente e executará com relação a ela. Se você estiver usando a mesma declaração preparada repetidamente, você pode, sem saber, também prepará-la repetidamente. Isso obviamente vem à tona quando você está lidando com tráfego pesado.

Então, obviamente, qual você para qual circunstância usar depende do seu caso de uso específico, mas espero que os detalhes acima ajudem a esclarecer o suficiente para que você possa tomar a melhor decisão em cada caso.

Atualizar


Dada a atualização no OP, essencialmente não há diferença quando a consulta precisa ser executada apenas uma vez, pois as consultas com argumentos são feitas como instruções preparadas nos bastidores.

Use os métodos diretos, por exemplo. DB.Query() e seus análogos, em vez de usar explicitamente instruções preparadas, pois resultará em um código-fonte um pouco mais simples.

Como as instruções preparadas, nesse caso, estão sendo utilizadas por motivos de segurança, pode valer a pena o esforço para lidar com as preocupações de segurança por outros meios e usar consultas de texto simples, pois isso melhorará o desempenho. Quaisquer ganhos, no entanto, podem ser irrelevantes, a menos que haja tráfego suficiente (ou se prevê que o tráfego cresça consideravelmente no futuro) para tornar a carga no servidor mais leve. Novamente, tudo se resume ao caso de uso do mundo real.

Para qualquer pessoa interessada em algumas métricas sobre a diferença entre declarações preparadas e consultas diretas de texto simples, há um bom artigo aqui (que também faz um excelente trabalho ao explicar muito do que foi dito acima).