sql >> Base de Datos >  >> RDS >> Mysql

declaración de preparación del controlador golang sql

Las diferencias pueden ser sutiles, a veces importantes y, a veces, inexistentes.

En general, una declaración preparada 1. se prepara con el servidor (SQL analizado, plan de ejecución generado, etc.), 2. se ejecuta con los parámetros adicionales y luego 3. se cierra. Le permite reutilizar el mismo SQL con diferentes parámetros pasados ​​cada vez, puede ayudar a protegerse contra la inyección de SQL, puede proporcionar algunas mejoras de rendimiento (controlador/protocolo específico, YMMV) y evitar pasos repetidos, como en la generación del plan de ejecución y el análisis de SQL en el preparar paso anterior.

Para alguien que escribe código fuente, una declaración preparada puede ser más conveniente que concatenar cadenas y enviarlas al servidor de base de datos.

El DB.Query() El método toma SQL como una cadena y cero o más argumentos (al igual que Exec() o QueryRow() ). Una cadena SQL sin argumentos adicionales consultará exactamente lo que escribió. Sin embargo, siempre que se proporcione una cadena SQL con marcadores de posición y argumentos adicionales, se está realizando una declaración preparada para usted bajo el capó.

El DB.Prepare() El método realiza explícitamente una declaración preparada, a la que luego pasa argumentos, como en:stmt.Exec(...args) .

Hay un par de cosas en las que vale la pena pensar, en términos de las diferencias entre los dos y por qué usar uno u otro.

Puede usar DB.Query() sin argumentos. Esto puede ser muy eficiente ya que puede omitir preparar --> ejecutar --> cerrar secuencia por la que pasa necesariamente la sentencia preparada.

También puede usarlo con argumentos adicionales y marcadores de posición en la cadena de consulta, y ejecutará una declaración preparada encubierta como mencioné anteriormente. El problema potencial aquí es que cuando realiza una serie de consultas, cada una da como resultado una declaración preparada bajo el capó. Dado que hay pasos adicionales involucrados, esto puede ser bastante ineficiente ya que se vuelve a preparar, ejecuta y cierra cada vez que realiza esa consulta.

Con una declaración preparada explícita, posiblemente pueda evitar esa ineficiencia mientras intenta reutilizar el SQL que preparó anteriormente, con argumentos potencialmente diferentes.

Pero eso no siempre funciona como cabría esperar... Debido al conjunto de conexiones subyacente que administra db/sql, su "conexión de base de datos" es bastante virtual. El DB.Prepare() El método preparará la declaración contra una conexión en particular y luego intentará recuperar esa misma conexión cuando sea el momento de ejecutar, pero si esa conexión no está disponible, simplemente tomará una que esté disponible y volverá a preparar y ejecutar contra eso. Si usa la misma declaración preparada una y otra vez, es posible que, sin saberlo, también la esté preparando una y otra vez. Obviamente, esto sale a la luz principalmente cuando estás lidiando con mucho tráfico.

Entonces, obviamente, cuál usted para qué circunstancia usa depende de su caso de uso específico, pero espero que los detalles anteriores lo ayuden a aclarar lo suficiente para que pueda tomar la mejor decisión en cada caso.

Actualizar

Dada la actualización en OP, esencialmente no hay diferencia cuando la consulta solo debe realizarse una vez, ya que las consultas con argumentos se realizan como declaraciones preparadas detrás de escena.

Utilice los métodos directos, p. DB.Query() y sus análogos, en lugar de usar declaraciones preparadas explícitamente, ya que resultará en un código fuente algo más simple.

Dado que las declaraciones preparadas, en este caso, se utilizan por razones de seguridad, puede valer la pena el esfuerzo de manejar los problemas de seguridad por otros medios y utilizar consultas de texto sin formato en su lugar, ya que mejorará el rendimiento. Cualquier ganancia, sin embargo, puede ser irrelevante a menos que haya suficiente tráfico (o se prevea que el tráfico crecerá considerablemente en el futuro) para necesitar aligerar la carga en el servidor. Una vez más, todo se reduce al caso de uso del mundo real.

Para cualquier persona interesada en algunas métricas sobre la diferencia entre declaraciones preparadas y consultas directas de texto sin formato, hay un buen artículo aquí (que también hace un excelente trabajo al explicar gran parte de lo anterior).