Bug #104247 | Connector / J performance is terrible when stored procedures are called at scale | ||
---|---|---|---|
Submitted: | 8 Jul 2021 5:38 | Modified: | 28 Oct 2021 11:19 |
Reporter: | Yoseph Phillips | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | Connector / J | Severity: | S5 (Performance) |
Version: | 8.0.25 | OS: | Any |
Assigned to: | MySQL Verification Team | CPU Architecture: | Any |
[8 Jul 2021 5:38]
Yoseph Phillips
[9 Jul 2021 9:18]
Alexander Soklakov
Hi Yoseph, Connector/J has the caching functionality you're looking for since version 3.1.2. Please check connection properties "cacheCallableStmts" and "callableStmtCacheSize". The "cacheCallableStmts" description says: "Should the driver cache the parsing stage of CallableStatements", here the "parsing stage" inclused not only the string parsing but also a call to metadata to fill in parameter types. You could check the test case testsuite.simple.CallableStatementTest.testSPCache() that's calling prepareCall() 10 times with and without cacheCallableStmts=true. With cacheCallableStmts=true there is only one I_S call in the general server log.
[5 Oct 2021 0:37]
Yoseph Phillips
Hi, We have done extensive testing with both cacheCallableStmts/callableStmtCacheSize and the global cache way described above, along with many other combinations. We have now been using the cacheCallableStmts/callableStmtCacheSize way in production for a couple of months and it is proving to be satisfactory. As this is a satisfactory solution this is no longer such a high priority for us. For anyone using stored procedures with a database pool of connections this is essential for acceptable performance. Some observations from our extensive load testing: * The global cache method described previously generally performs better than the cacheCallableStmts/callableStmtCacheSize way, however can have issues with this simple implementation when lots of threads are bottle necked waiting on the Java lock. Also the global cache way uses less RAM as it only needs one copy of information, not one copy per connection, however for us we have enough RAM for the cacheCallableStmts/callableStmtCacheSize way. * Doing both the global cache method and the cacheCallableStmts/callableStmtCacheSize method together gave the best overall performance - however we won't do this in production as Connector / J doesn't have the global cache method * Using a ThreadLocal was another option, which avoided the global Java lock, and had a copy of the Meta Data for each Java Thread, instead of a copy for each Connection * Bottom line was all of these methods were significantly better than no caching at all, and the difference between the above methods were not significant enough that users would notice a difference. Thanks
[28 Oct 2021 11:19]
Filipe Silva
Posted by developer: Thank you for the detailed feedback. I'm closing this issue as "not a bug". Please re-open it of file a new one if the problem arises again due to a different reason.