Skip to content
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

Slow Query in JdbcJobInstanceDao.getLastJobInstance() #4024

Closed
jickoo opened this issue Nov 3, 2021 · 0 comments
Closed

Slow Query in JdbcJobInstanceDao.getLastJobInstance() #4024

jickoo opened this issue Nov 3, 2021 · 0 comments
Labels
Milestone

Comments

@jickoo
Copy link

jickoo commented Nov 3, 2021

I use spring-batch-core 4.3.3.
Slow query has occured in FIND_LAST_JOB_INSTANCE_BY_JOB_NAME sql.

public class JdbcJobInstanceDao extends AbstractJdbcBatchMetadataDao implements
JobInstanceDao, InitializingBean {

// ...
	private static final String FIND_LAST_JOB_INSTANCE_BY_JOB_NAME = "SELECT JOB_INSTANCE_ID, JOB_NAME from %PREFIX%JOB_INSTANCE I1 where" +
			" I1.JOB_NAME = ? and I1.JOB_INSTANCE_ID in (SELECT max(I2.JOB_INSTANCE_ID) from %PREFIX%JOB_INSTANCE I2 where I2.JOB_NAME = ?)";

// ...
	@Override
	@Nullable
	public JobInstance getLastJobInstance(String jobName) {
		try {
			return getJdbcTemplate().queryForObject(
					getQuery(FIND_LAST_JOB_INSTANCE_BY_JOB_NAME),
					new Object[] { jobName, jobName },
					new JobInstanceRowMapper());
		} catch (EmptyResultDataAccessException e) {
			return null;
		}
	}
// ...

Executed query.

SELECT
	JOB_INSTANCE_ID,
	JOB_NAME
FROM
	BATCH_JOB_INSTANCE I1
WHERE
	I1.JOB_NAME IN 'myJob'
	AND I1.JOB_INSTANCE_ID IN (
		SELECT
			MAX(I2.JOB_INSTANCE_ID)
		FROM
			BATCH_JOB_INSTANCE I2
		WHERE
			I2.JOB_NAME = 'myJob'
	) 
;

Currently I have about 10,000 rows.
My db socket timeout is 6 seconds and Exception occurred because the above query exceeded 6 seconds.
For MySql query performance, it seems that the query needs to be modified as follows.

solution 1

do not use 'IN' query

SELECT
	JOB_INSTANCE_ID,
	JOB_NAME
FROM
	BATCH_JOB_INSTANCE I1
WHERE
	I1.JOB_NAME = 'myJob'
	AND I1.JOB_INSTANCE_ID = (
		SELECT
			MAX(I2.JOB_INSTANCE_ID)
		FROM
			BATCH_JOB_INSTANCE I2
		WHERE
			I2.JOB_NAME = 'myJob'
	)
; 

solution 2

In my case, I solved it by adding an index.

ALTER TABLE BATCH_JOB_INSTANCE 
ADD INDEX JOB_INST_NAME_ID(JOB_NAME, JOB_INSTANCE_ID);

Thank you.

@jickoo jickoo added status: waiting-for-triage Issues that we did not analyse yet type: bug labels Nov 3, 2021
@fmbenhassine fmbenhassine added this to the 5.0.2 milestone Mar 29, 2023
@fmbenhassine fmbenhassine added the for: backport-to-4.3.x Issues that will be back-ported to the 4.3.x line label Mar 29, 2023
@fmbenhassine fmbenhassine changed the title Slow Query in JdbcJobInstanceDao.getLastJobInstance() on MySQL Slow Query in JdbcJobInstanceDao.getLastJobInstance() Mar 29, 2023
fmbenhassine added a commit that referenced this issue Mar 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants