Skip to content

Improve performance of JdbcStepExecutionDao::getLastStepExecution - #4798

Closed
quaff wants to merge 1 commit into
spring-projects:mainfrom
quaff:patch-14
Closed

Improve performance of JdbcStepExecutionDao::getLastStepExecution#4798
quaff wants to merge 1 commit into
spring-projects:mainfrom
quaff:patch-14

Conversation

@quaff

@quaff quaff commented Mar 27, 2025

Copy link
Copy Markdown
Contributor
  1. Use SQL order by clause instead of Java Comparator
  2. Limit result set size to 1

@quaff

quaff commented Mar 27, 2025

Copy link
Copy Markdown
Contributor Author

Alternatively, we could use SE.STEP_EXECUTION_ID IN (SELECT MAX(STEP_EXECUTION_ID) FROM ...) to align with other queries, but there is a risk to break existing behavior since CREATE_TIME is not considered for comparing.

https://github.com/spring-projects/spring-batch/compare/main...quaff:spring-batch:patch-16?expand=1

@fmbenhassine fmbenhassine added the status: waiting-for-reporter Issues for which we are waiting for feedback from the reporter label Jun 3, 2025
@fmbenhassine fmbenhassine added status: feedback-provided Issues for which the feedback requested from the reporter was provided and removed status: waiting-for-reporter Issues for which we are waiting for feedback from the reporter labels Jun 4, 2025
@hpoettker

hpoettker commented Jun 4, 2025

Copy link
Copy Markdown
Contributor

The suggested change is basically a revert of the fix for #4657.

I'm not sure whether the performance gain is worth it, compared to the risk of re-introducing the previous issue.

@quaff

quaff commented Jun 5, 2025

Copy link
Copy Markdown
Contributor Author

The suggested change is basically a revert of the fix for #4657.

I'm not sure whether the performance gain is worth it, compared to the risk of re-introducing the previous issue.

This commit will not query all matched rows but only first row.

statement.setMaxRows(1); // limit max rows to 1

if (rs.next()) {
// only first row is used.
}

@quaff

quaff commented Jun 5, 2025

Copy link
Copy Markdown
Contributor Author

Our DBA has not been able to find a solution to improve the performance with an additional index.
What we did find out is that, by removing the ORDER BY, we get the result (typically just a single row in the normal case) in a matter of milliseconds. But with the ORDER BY, it takes ~ 60 seconds.

It's weird, but I'm OK if this PR is rejected.

@fmbenhassine fmbenhassine added this to the 6.0.0-RC1 milestone Sep 11, 2025
@fmbenhassine

Copy link
Copy Markdown
Contributor

I am not a big fan of sorting things on the application side if we can do it on the database side, so this PR has its added value if we do not include any regression or performance degradation as reported in #4657. So basically we moved this from Java to the DB in #891 with 62a8f44, then from the DB to Java in #4657 with 5a62de9, and now back again to the DB with this PR.

I could not find the reason we merged #4657, but I guess it was due to this #4657 (comment). I suggested to use LIMIT 1 or equivalent, but in fact the syntax could differ between DB providers which is more complex. Probably since we were targeting that fix for a patch release from what I see 5.1.3, we accepted to move the logic back from the DB to Java. But it's probably time to introduce a more sophisticated / proper approach to do it on the DB side.

This commit will not query all matched rows but only first row.

Is using statement.setMaxRows(1); // limit max rows to 1 somehow equivalent to something like LIMIT 1? I mean if we can avoid having to provide a different limiting query depending on the DB (TOP 1 or FETCH FIRST 1 ROW ONLY or WHERE ROWNUM <= 1), that would be better.

Thoughts?

I'm not sure whether the performance gain is worth it, compared to the risk of re-introducing the previous issue.

@hpoettker I agree. I don't know @quaff if you had a chance to benchmark this change? It would be great if we have a baseline to measure the performance improvement/degradation and decide if this change is worth it.

@fmbenhassine fmbenhassine added status: waiting-for-reporter Issues for which we are waiting for feedback from the reporter and removed status: feedback-provided Issues for which the feedback requested from the reporter was provided labels Oct 21, 2025
@fmbenhassine fmbenhassine removed this from the 6.0.0-RC1 milestone Oct 21, 2025
1. Use SQL order by clause instead of Java Comparator
2. Limit result set size to 1

Signed-off-by: Yanming Zhou <zhouyanming@gmail.com>
@quaff

quaff commented Oct 22, 2025

Copy link
Copy Markdown
Contributor Author

Is using statement.setMaxRows(1); // limit max rows to 1 somehow equivalent to something like LIMIT 1?

I think most JDBC drivers honer the max rows.

I don't know @quaff if you had a chance to benchmark this change? It would be great if we have a baseline to measure the performance improvement/degradation and decide if this change is worth it.

I didn't, @jpraet could you verify this patch works for you since you reported #4657?

@jpraet

jpraet commented Nov 5, 2025

Copy link
Copy Markdown
Contributor

Hi, we have since upgraded from DB2 10 to DB2 11 and I can no longer reproduce the slow query reported in #4657.
So, no objections from my side to go ahead with this PR and move sorting back to the database.

@fmbenhassine fmbenhassine added pr-for: enhancement in: core and removed status: waiting-for-reporter Issues for which we are waiting for feedback from the reporter labels Nov 5, 2025
@fmbenhassine fmbenhassine added this to the 6.0.0-RC2 milestone Nov 5, 2025
@fmbenhassine

Copy link
Copy Markdown
Contributor

@jpraet Thank you for your feedback! Just in time to include this in 6.0.0-RC2.

Rebased and merged as 1cad039. Thank you @quaff for your contribution 👍

fmbenhassine pushed a commit that referenced this pull request Jun 2, 2026
Push the step name filter, ordering (createTime DESC, then stepExecutionId
DESC), and limit(1) down to MongoDB instead of fetching all step executions
for the job instance and filtering/sorting in Java.

This mirrors the optimization applied to the JDBC variant in #4798 and
addresses the existing `// TODO optimize the query` marker.

Resolves #5385

Signed-off-by: Seonwoo Jung <laborlawseon@kap.kr>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants