-
Notifications
You must be signed in to change notification settings - Fork 38.2k
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
Improve default setNull
performance on PostgreSQL and MS SQL Server (e.g. for NamedParameterJdbcTemplate
batch updates)
#25679
Comments
Have you tried |
It seems |
@jhoeller Could you explain why not simply call |
As for why not simply call
|
spring.jdbc.getParameterType.ignore=true did the trick, thanks! |
@jhoeller I assume all modern databases allow non-typed Null, if it's true, |
Reasonable defaults, that's what life is about :) |
We're happy to refine our default assumptions there. However, a few years ago, there were only a few databases supporting untyped I'd particularly like to learn about recent driver behavior with MySQL and PostgreSQL there. We're effectively using |
A StackOverflow answer about support for A more recent discussion thread about PostgreSQL null handling (https://www.postgresql-archive.org/quot-could-not-determine-data-type-of-parameter-quot-with-timestamp-td5995489.html) suggests that Another interesting thread on StackOverflow (https://stackoverflow.com/questions/37942063/slow-insert-on-postgresql-using-jdbc) suggests that the pgjdbc-ng driver caches parameter data and is therefore much faster with our default settings. I'll consider revising our default algorithm to take recent driver updates into account, reopening this issue for it. There might not be much that we can do about PostgreSQL specifically but this is nevertheless worth a fresh look now with 2020-era drivers. |
Great to hear that you're revisiting this implementation. Setting null with Types.NULL indeed works for PostgresSQL (JDBC) 42.2.12 and C3P0 0.9.5.5. Adding a bit more information, here is the result of our performance test JdbcTemplateBatch 1: 10925 records/sec. Average: 11,120 NamedJdbcTemplate with default configurationBatch 1: 312 records/sec. Average: 342.2 records/sec. NamedJdbcTemplate with spring.jdbc.getParameterType.ignore=trueBatch 1: 10384 records/sec. Average: 10,726 records/sec. So in general, JdbcTemplate is a bit faster than NamedJdbcTemplate with spring.jdbc.getParameterType.ignore=true (around 4%), but in the same order of magnitude. However, there's a huge performance drop by using NamedJdbcTemplate with the default configuration. |
@jhoeller I'm wondering why |
It seems like Line 69 in 3a0f309
|
Hmm |
@jhoeller can you point me to the concrete caching approach you are referring to? |
@davecramer it looks like @vlsi was pretty much working in that direction with pgjdbc/pgjdbc#621 already. I suppose a PreparedStatement-level cache would go a long way, a Connection-level cache would be even better. All we really need is On Spring's side, we just need that metadata for passing in a SQL type to a |
@davecramer, reviewing other JDBC driver implementations in that respect, the key-based caching approach that @vlsi considered was probably more sophisticated than necessary. The common driver implementations seem to simply cache the |
@jhoeller , thank you for the clarification. Let me see if I can implement the MVP. |
setNull
performance on PostgreSQL (e.g. for NamedParameterJdbcTemplate
batch updates)
I had performance problems in production due to the setNull using MSSQL with the official driver in the latest version available (12.4.1) and JDBCTemplate.update(), when adding the parameter I would like to understand when the use of this parameter can actually be something negative and if there is any relationship between drivers where it causes problems, currently I use the official mssql driver and the postgresql driver for some demands, is there any way that Do you recommend so that I can test these drivers? If possible, I would like to always set the value of Thank you in advance if anyone can clarify these doubts, I don't understand in depth how the drivers work and so it's difficult for me to know exactly which scenarios are problematic with the mentioned parameter. |
I wasn't aware of such a dramatic performance impact on SQL Server yet, this looks like a reason to prefer the bypass (without a For H2, HSQLDB, Derby and MySQL, type information does not matter for null values either but On the other side, to the best of my knowledge, type information for null values is important on Oracle, Sybase and DB2, with All in all, I'm inclined to implement a default bypass for PostgreSQL and MS SQL Server for the case where |
setNull
performance on PostgreSQL (e.g. for NamedParameterJdbcTemplate
batch updates)setNull
performance on PostgreSQL and MS SQL Server (e.g. for NamedParameterJdbcTemplate
batch updates)
We've been investigating an issue where we had a 100x performance drop when switching from JdbcTemplate to NamedParameterJdbcTemplate in batch update operations.
We found out that the root cause is the handling of null values by StatementCreatorUtils:setNull, which in turn calls getParameterMetadata from the connection. It seems this issue a database call for every row to be inserted (call stack from profiler attached) which basically kills the performance gains of the batch insert.
We're using Postgres as back-end database. Spring JDBC 5.2.5.
Thanks.
The text was updated successfully, but these errors were encountered: