¿Cuál es la diferencia entre cachePrepStmts y useServerPrepStmts en MySQL JDBC Driver?
database caching (1)
El controlador JDBC de MySQL define estas dos propiedades como:
useServerPrepStmts - ¿Usar declaraciones preparadas del lado del servidor si el servidor las admite?
cachePrepStmts: ¿Debería el controlador almacenar en caché la etapa de análisis de PreparedStatements de las declaraciones preparadas del lado del cliente, la "verificación" de la idoneidad de las declaraciones preparadas del lado del servidor y las declaraciones preparadas del lado del servidor?
¿Es la declaración preparada del lado del cliente una forma de reutilizar los objetos PreparedStatements
?
Si useServerPrepStmts
está habilitado, ¿qué se está almacenando exactamente en caché, ya que MySQL no tiene un caché de plan de ejecución de todos modos ?
Primero, es importante distinguir entre declaraciones preparadas por el cliente y el servidor.
Declaraciones preparadas por el cliente
Las declaraciones preparadas por el cliente son declaraciones preparadas "emuladas". Esto significa que la cadena de la sentencia de 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 sentencia SQL completa se envía al servidor en cada ejecución. Puedes usar el registro general para investigar cómo funciona esto. p.ej
el siguiente código:
ps=conn.prepareStatement("select ?")
ps.setInt(1, 42)
ps.executeQuery()
ps.setInt(1, 43)
ps.executeQuery()
se mostraría en el registro:
255 Query select 42
255 Query select 43
La "consulta" indica que, en el nivel de protocolo, se COM_QUERY
un comando COM_QUERY
con la siguiente cadena de declaración.
Declaraciones preparadas por el servidor
Las declaraciones preparadas por el servidor son declaraciones "verdaderas" preparadas, 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 cuando configuras useServerPrepStmts=true
. La cadena de la declaración solo se envía una vez al servidor con una llamada COM_STMT_PREPARE
(documentada here ). Cada ejecución se realiza enviando un COM_STMT_EXECUTE
con el identificador de la declaración preparada 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 las 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
Puedes ver que la declaración 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 los marcadores de posición se envían del cliente al servidor para cada ejecución.
Declaraciones preparadas en caché
Muchos grupos de conexiones almacenarán en caché las declaraciones preparadas para los usos de una conexión, lo que significa que si llama a conn.prepareStatement("select ?")
, conn.prepareStatement("select ?")
la misma instancia de PreparedStatement
en llamadas sucesivas con la misma cadena de instrucción. Esto es útil para evitar preparar repetidamente la misma cadena en el servidor cuando las conexiones se devuelven al conjunto 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 el servidor), así como la "preparación" 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. Esta verificación es costosa debido a que requiere un viaje de ida y vuelta al servidor. La opción también almacenará en caché el resultado de esta comprobación.
Espero que esto ayude.