How do i take advantage of MySQL's ability to cache prepared statements? One reason to use prepared statements is that there is no need to send the prepared statement itself multiple times if the same prepared statement is to be used again.
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb" +
"?cachePrepStmts=true", "user", "pass");
for (int i = 0; i < 5; i++) {
PreparedStatement ps = conn.prepareStatement("select * from MYTABLE where id=?");
ps.setInt(1, 1);
ps.execute();
}
conn.close()
When running the above Java example I see 5 pairs of Prepare and Execute commands in the mysqld log file. Moving the ps assignment outside of the loop results in a single Prepare and 5 Execute commands of course. The connection parameter "cachePrepStmts=true" doesn't seem to make any difference here.
When running a similar program using Spring and Hibernate the number of Prepare commands sent (1 or 5) depends on whether the cachePrepStmts connection parameter is enabled. How does Hibernate execute prepared statements to take advantage of the cachePrepStmts setting? Is it possible to mimic this using pure JDBC?
I was running this on MySQL Server 4.1.22 and mysql-connector-java-5.0.4.jar
MySQL determines the queries to cache by examining the query_cache_type variable. Setting this value to 0 or OFF prevents caching or retrieval of cached queries. You can also set it to 1 to enable caching for all queries except for ones beginning with the SELECT SQL_NO_CACHE statement.
Open terminal and run the following command to open MySQL configuration file. We have enabled query cache by setting query_cache_type variable to 1, with individual query cache as 256Kb and total cache as 10Mb. You can change the values of query_cache_size and query_cache_limit as per your requirements.
Before a query result is fetched from the query cache, MySQL checks whether the user has SELECT privilege for all databases and tables involved. If this is not the case, the cached result is not used. If a query result is returned from query cache, the server increments the Qcache_hits status variable, not Com_select .
Prepared statements reduce the need to compile the SQL statements. You can improve the performance of agents and integration servers by using prepared statement caching, which caches executable statements that are used repeatedly. By default, prepared statement caching is enabled for agents and integration servers.
You should prepare your statement only once, outside of the loop, and then bind the parameters in the loop. This is why prepared statements have bind parameters - so you can reuse the prepared statement.
Hibernate does exactly this, treating all SQL as a prepared statement behind the scenes, though you can obviously abuse this if you use literal rather than bind parameters.
Is it possible to mimic this using pure JDBC?
Is this not in fact what you've done by moving your prepared statement call out of the loop?
I may be misunderstanding the way the MySQL cache works, but does the log file necessarily report the cache's work? It may be that Spring or Hibernate has its own intermediate cache that checks the prepared statements against those sent earlier. It might be that that you're seeing when you run the program with Spring. That would mean doing a bit of tracing with your system to see if the mysqld log is just reporting the statements it's been sent, regardless of how it deals with them.
You also need to set the statement cache size on the connection instance. I assume the default cache size is 0. Hence nothing would be cached.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With