我正在调查使用Spring Batch 4.2.0和Postgres 14.5的Sping Boot 应用程序的性能问题,并遇到了一个有趣的问题。
下面是其中一个顶级查询。解释计划显示它执行一个FTS(实际上是两个)。查询Postgres端:
SELECT SE.STEP_EXECUTION_ID, SE.STEP_NAME, SE.START_TIME, SE.END_TIME, SE.STATUS, SE.COMMIT_COUNT, SE.READ_COUNT, SE.FILTER_COUNT, SE.WRITE_COUNT,
SE.EXIT_CODE, SE.EXIT_MESSAGE, SE.READ_SKIP_COUNT, SE.WRITE_SKIP_COUNT, SE.PROCESS_SKIP_COUNT, SE.ROLLBACK_COUNT, SE.LAST_UPDATED, SE.VERSION,
JE.JOB_EXECUTION_ID, JE.START_TIME, JE.END_TIME, JE.STATUS, JE.EXIT_CODE, JE.EXIT_MESSAGE, JE.CREATE_TIME, JE.LAST_UPDATED, JE.VERSION
from N_BATCH_JOB_EXECUTION JE, N_BATCH_STEP_EXECUTION SE
where
SE.JOB_EXECUTION_ID in
(SELECT JOB_EXECUTION_ID
from N_BATCH_JOB_EXECUTION
where JE.JOB_INSTANCE_ID = $1)
and SE.JOB_EXECUTION_ID = JE.JOB_EXECUTION_ID
and SE.STEP_NAME = $2
order by SE.START_TIME desc, SE.STEP_EXECUTION_ID desc
解释计划:
Sort (cost=154.08..154.11 rows=13 width=217)
Sort Key: se.start_time DESC, se.step_execution_id DESC
-> Hash Join (cost=69.71..153.83 rows=13 width=217)
Hash Cond: (se.job_execution_id = je.job_execution_id)
Join Filter: (SubPlan 1)
-> Bitmap Heap Scan on n_batch_step_execution se (cost=4.49..88.54 rows=26 width=156)
Recheck Cond: ((step_name)::text = 'notf0270f8e50fd95b44da8b34cb1ea829cc74'::text)
-> Bitmap Index Scan on n_batch_step_exec_step_name_job_exec_id_idx (cost=0.00..4.48 rows=26 width=0)
Index Cond: ((step_name)::text = 'notf0270f8e50fd95b44da8b34cb1ea829cc74'::text)
-> Hash (cost=45.10..45.10 rows=1610 width=77)
-> Seq Scan on n_batch_job_execution je (cost=0.00..45.10 rows=1610 width=77)
SubPlan 1
-> Result (cost=0.00..45.10 rows=1610 width=8)
One-Time Filter: (je.job_instance_id = 1)
-> Seq Scan on n_batch_job_execution (cost=0.00..45.10 rows=1610 width=8)
这个查询对我来说似乎不太正确,试图使它更好,得到一些东西,并决定检查原始的。(JdbcStepExecutionDao.java),看起来是正确的。但它略有不同,基本上,子查询不使用外部查询中定义的别名(其中JOB_INSTANCE_ID =...而不是**JE.**JOB_INSTANCE_ID = ...)
where
SE.JOB_EXECUTION_ID in
(SELECT JOB_EXECUTION_ID
from N_BATCH_JOB_EXECUTION
where JOB_INSTANCE_ID = $1)
说明方案看起来更好:
Sort (cost=17.74..17.75 rows=1 width=217)
Sort Key: se.start_time DESC, se.step_execution_id DESC
-> Nested Loop (cost=0.59..17.73 rows=1 width=217)
-> Nested Loop (cost=0.30..16.35 rows=1 width=77)
-> Index Scan using n_batch_job_execution_job_instance_id_idx on n_batch_job_execution (cost=0.15..8.17 rows=1 width=8)
Index Cond: (job_instance_id = 1)
-> Index Scan using n_batch_job_execution_pkey on n_batch_job_execution je (cost=0.15..8.17 rows=1 width=69)
Index Cond: (job_execution_id = n_batch_job_execution.job_execution_id)
-> Index Scan using n_batch_step_exe_idx on n_batch_step_execution se (cost=0.29..1.37 rows=1 width=156)
Index Cond: (job_execution_id = je.job_execution_id)
Filter: ((step_name)::text = 'notf0270f8e50fd95b44da8b34cb1ea829cc74'::text)
我的问题是查询是如何被重写的?也许是Postgres服务器做的,也许是JDBC驱动程序或其他层?
1条答案
按热度按时间qvsjd97n1#
我的问题是查询是如何被重写的?也许是Postgres服务器做的,也许是JDBC驱动程序或其他层?
Spring Batch不会重写查询。您在代码中看到的查询是发送到数据库的查询。