Bug #106648 ResultSet::getDate creates unnecessary stack trace
Submitted: 6 Mar 8:20 Modified: 9 Mar 9:52
Reporter: Jürgen Lind Email Updates:
Status: Verified Impact on me:
Category:Connector / J Severity:S3 (Non-critical)
Version: OS:Any
Assigned to: CPU Architecture:Any

[6 Mar 8:20] Jürgen Lind
We experienced severe performance differences between a standalone Java application that accesses an ResultSet and a Spring application that uses the same code. Upon further investigation, we discovered that the ResultSet implementation of the getDate-Method generates an SQLWarning regardless of whether it is logged or not. Depending on depth of the current stack, there is a huge performance penalty in generating the stack. 

How to repeat:
Use ResultSet::getDate in an application with a low number of stack frames and compare with deeply nested code.

Suggested fix:
Create the stack trace only if it es logged.
[6 Mar 8:21] Jürgen Lind
Changed title to better reflect the problem area
[7 Mar 10:53] MySQL Verification Team

What warning do you get?

[7 Mar 13:00] Jürgen Lind
The warning generated is a ResultSet.PrecisionLostWarning. For me the problem seems to be the fact, that the ResultSetImpl registers iteself as the WarningListener of the SqlDateValueFactory. This triggers the call of the warningEncountered Method of the ResultSet which creates the stackTrace via the super() calls.
[7 Mar 13:16] MySQL Verification Team

Weird that getDate produces this warning. Anyhow, I have issues reproducing this, what kind of connection string is your spring app using? Are you using prepared statements (server or client side?)?

If you maybe have a minimal test case I can play with as the quick test I whipped up did not reproduce this

[7 Mar 13:31] Jürgen Lind
The testcase where I have encountered the issue is actually quite simple
- in the database, I have a column of type datetime(6)
- I do not use any spring-stuff to get the connection, I'm using the DriverManager directly
- The connection string has no parameters whatsoever
- The method to extract the value from the ResultSet is getDate(String)

If I switch to using getTimestamp, the performance is much, much better.
[9 Mar 9:52] MySQL Verification Team