Primero, es importante distinguir entre declaraciones preparadas por el cliente y por el servidor.
Declaraciones preparadas por el cliente
Los extractos preparados por el cliente son extractos preparados "emulados". Esto significa que la cadena de sentencia SQL se tokeniza en el lado del cliente y cualquier marcador de posición se reemplaza con valores literales antes de enviar la sentencia al servidor para su ejecución. Una declaración SQL completa se envía al servidor en cada ejecución. Puede usar el registro general para investigar cómo funciona esto. por ejemplo
el siguiente código:
ps=conn.prepareStatement("select ?")
ps.setInt(1, 42)
ps.executeQuery()
ps.setInt(1, 43)
ps.executeQuery()
mostraría en el registro:
255 Query select 42
255 Query select 43
La "consulta" indica que, a nivel de protocolo, un COM_QUERY
El comando se envía con la siguiente cadena de declaración.
Declaraciones preparadas por el servidor
Las declaraciones preparadas por el servidor son declaraciones preparadas "verdaderas", lo que significa que el texto de la consulta se envía al servidor, se analiza y el marcador de posición y la información del resultado se devuelven al cliente. Esto es lo que obtienes al configurar useServerPrepStmts=true
. La cadena de declaración solo se envía al servidor una vez con un COM_STMT_PREPARE
llamar (documentado aquí
). Cada ejecución se realiza enviando un COM_STMT_EXECUTE
con el identificador de declaración preparado y los valores literales para sustituir los marcadores de posición.
Para contrastar con el ejemplo preparado por el cliente, podemos usar un bloque de código similar (pero esta vez con declaraciones preparadas por el servidor habilitadas):
ps2=conn2.prepareStatement("select ?")
ps2.setInt(1, 42)
ps2.executeQuery()
ps2.setInt(1, 43)
ps2.executeQuery()
Y el registro mostraría:
254 Prepare select ?
254 Execute select 42
254 Execute select 43
Puede ver que la sentencia está preparada antes de ser ejecutada. El registro nos está haciendo un favor y muestra la declaración completa para la ejecución pero, de hecho, solo los valores de marcador de posición se envían del cliente al servidor para cada ejecución.
Almacenamiento en caché de declaraciones preparadas
Muchos grupos de conexiones almacenarán en caché las declaraciones preparadas a través de los usos de una conexión, lo que significa que si llama a conn.prepareStatement("select ?")
, devolverá el mismo PreparedStatement
instancia en llamadas sucesivas con la misma cadena de instrucción. Esto es útil para evitar preparar la misma cadena en el servidor repetidamente cuando las conexiones se devuelven al grupo entre transacciones.
La opción MySQL JDBC cachePrepStmts
almacenará en caché las declaraciones preparadas de esta manera (tanto las declaraciones preparadas por el cliente como por el servidor), así como también almacenará en caché la "preparabilidad" de una declaración. Hay algunas declaraciones en MySQL que no se pueden preparar en el lado del servidor. El controlador intentará preparar una declaración en el servidor si cree que es posible y, si la preparación falla, recurrirá a una declaración preparada por el cliente. Este cheque es costoso debido a que requiere un viaje de ida y vuelta al servidor. La opción también almacenará en caché el resultado de esta verificación.
Espero que esto ayude.