-
Notifications
You must be signed in to change notification settings - Fork 435
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] Performance issue with setNull(Types.DECIMAL) on a decimal column #1106
Comments
Hi @sns-seb, thanks for letting us know. The team will look into this. What SQL Server version was used here? 12.0.x can refer to SQL Azure or 2014. |
Hi @rene-ye, it was SQL Server 2014. I'll update the description |
Hi @sns-seb, the performance "degradation" in this issue has to do with how the driver caches prepared statements. The image below is an example of the driver calls to the server when calling executeBatch() repeatedly with the same datatypes: As you can see, the driver calls sp_prepexec on the second batch, and proceeds to execute the rest of the batch with sp_execute. This is a performance improvement discussed in #166. When datatypes are switched (as in the case above where the test is interchanging between Decimal and Double), the driver will constantly re-prepare statements: We can enable statement pooling to resolve this issue. Adding If you have any more questions regarding this behavior please feel free to ask. TL;DR: Issue isn't caused by setNull() with Double/Decimal. The driver by default attempts some prepared statement caching, and constantly changing datatypes breaks this simple attempt. |
thanks for the detailed and clear explanation @rene-ye I guess this issue can be closed, then? I'm wondering whether a warning (or even an error) would make sense in this case, though. |
I'd assume there would be cases where frameworks are changing underlying datatypes unbeknownst to the user. Regardless, I see your point, we'll think about adding a warning or some kind of logging. |
Driver version
7.2.2.jre8, 7.2.2.jre11, 7.3.1-preview.jre11
SQL Server version
SQL Server 2014 Standard Edition 12.00.5571.0.v1 on Amazon RDS (db.m5.xlarge)
SQL Server 2014 Enterprise Edition 12.00.5571.0.v1 on Amazon RDS (db.m5.4xlarge)
Client Operating System
Amazon Linux 2 AMI 2.0.20190313 x86_64 HVM gp2 (t3.medium)
JAVA/JVM version
Table schema
See reproducer
Problem description
Usage of
java.sql.PreparedStatement.setNull(int parameterIndex, int sqlType)
withjava.sql.Types.DECIMAL
instead ofjava.sql.Types.DOUBLE
to set a null value on a column of SQL typedecimal
leads to poor JDBC batch insert performance and constant drop of throughput over time.We observed that performing massive inserts always setting the
decimal
column tonull
, the performance was nominal.The performance impact would only kick in if column was sometime populated with
null
, sometime with a double usingjava.sql.PreparedStatement.setDouble(int parameterIndex, double x)
.Some figures, collected in the environment described above, measured from the Java side (see reproducer) attempting to insert 3 millions rows in batches of 250 rows:
setNull(Types.DOUBLE)
aloneStable at 83k / seconds
setNull(Types.DOUBLE)
mixed with calls tosetDouble()
Stable at 83k / seconds
setNull(Types.DECIMAL)
aloneStable at 83k / seconds
setNull(Types.DECIMAL)
mixed with calls tosetDouble()
unstable (variations from one batch to the next) with at most 17k/s at the beginning of the run, rapidly dropping towards 10k/s and below
JDBC trace logs
Changing log level is not an option because they would affect performance
Reproduction code
The text was updated successfully, but these errors were encountered: