Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between cachePrepStmts and useServerPrepStmts in MySQL JDBC Driver

The MySQL JDBC Driver defines these two properties as:

  • useServerPrepStmts - Use server-side prepared statements if the server supports them?

  • cachePrepStmts - Should the driver cache the parsing stage of PreparedStatements of client-side prepared statements, the "check" for suitability of server-side prepared and server-side prepared statements themselves?

Is the client-side prepared statement a way to reuse the PreparedStatements objects?

If the useServerPrepStmts is enabled, what is exactly being cached, since MySQL doesn't have an execution plan cache anyway?

like image 815
Vlad Mihalcea Avatar asked Aug 29 '15 13:08

Vlad Mihalcea


People also ask

What is cachePrepStmts?

Caching Prepared Statements The MySQL JDBC option cachePrepStmts will cache prepared statements in this way (both client and server prepared statements) as well as cache the "preparability" of a statement. There are some statements in MySQL that are not preparable on the server side.

What is the JDBC connection string for MySQL?

Connection URL: The connection URL for the mysql database is jdbc:mysql://localhost:3306/sonoo where jdbc is the API, mysql is the database, localhost is the server name on which mysql is running, we may also use IP address, 3306 is the port number and sonoo is the database name.

How do I know if MySQL JDBC driver is installed?

You can determine the version of the JDBC driver that you installed, by calling the getDriverVersion method of the OracleDatabaseMetaData class. You can also determine the version of the JDBC driver by executing the following commands: java -jar ojdbc5. jar.


1 Answers

First, it's important to distinguish between client and server prepared statements.

Client Prepared Statements

Client prepared statements are "emulated" prepared statements. This means that the SQL statement string is tokenized on the client side and any placeholders are replaced with literal values before sending the statement to the server for execution. A complete SQL statement is sent to the server on every execution. You can use the general log to investigate how this works. e.g.

the following code:

ps=conn.prepareStatement("select ?")
ps.setInt(1, 42)
ps.executeQuery()
ps.setInt(1, 43)
ps.executeQuery()

would show in the log:

255 Query  select 42
255 Query  select 43

The "query" indicates that, on the protocol level, a COM_QUERY command is sent with the statement string following.

Server Prepared Statements

Server prepared statements are "true" prepared statements meaning that the query text is sent to the server, parsed, and placeholder and result information is returned to the client. This is what you get when setting useServerPrepStmts=true. The statement string is only ever sent to the server one time with a COM_STMT_PREPARE call (documented here). Each execution is performed by sending a COM_STMT_EXECUTE with the prepared statement handle and the literal values to substitute for the placeholders.

To contrast with the client prepared example, we can use a similar block of code (but this time with server prepared statements enabled):

ps2=conn2.prepareStatement("select ?")
ps2.setInt(1, 42)
ps2.executeQuery()
ps2.setInt(1, 43)
ps2.executeQuery()

And the log would show:

254 Prepare    select ?
254 Execute    select 42
254 Execute    select 43

You can see that the statement is prepared before being executed. The log is doing us a favor and showing the complete statement for the execution but, in fact, only the placeholder values are sent from client to server for each execution.

Caching Prepared Statements

Many connection pools will cache prepared statements across uses of a connection meaning that if you call conn.prepareStatement("select ?"), it will return the same PreparedStatement instance on successive calls with the same statement string. This is useful to avoid preparing the same string on the server repeatedly when connections are returned to the pool between transactions.

The MySQL JDBC option cachePrepStmts will cache prepared statements in this way (both client and server prepared statements) as well as cache the "preparability" of a statement. There are some statements in MySQL that are not preparable on the server side. The driver will try to prepare a statement on the server if it believes it to be possible and, if the prepare fails, fall back to a client prepared statement. This check is expensive due to requiring a round-trip to the server. The option will also cache the result of this check.

Hope this helps.

like image 139
Jess Balint Avatar answered Oct 14 '22 21:10

Jess Balint