Spring Batch的元数据表不会被自动清理, 所以我尝试手动清理(前提是清理过程中其他批次进程正常执行)。
当我尝试清理
BATCH_JOB_EXECUTION_PARAMS
桌子时,我发现桌子被锁了。
表结构为:
CREATE TABLE BATCH_JOB_EXECUTION_PARAMS (
JOB_EXECUTION_ID BIGINT NOT NULL ,
PARAMETER_NAME VARCHAR(100) NOT NULL ,
PARAMETER_TYPE VARCHAR(100) NOT NULL ,
PARAMETER_VALUE VARCHAR(2500) ,
IDENTIFYING CHAR(1) NOT NULL ,
constraint JOB_EXEC_PARAMS_FK foreign key (JOB_EXECUTION_ID)
references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ENGINE=InnoDB;
SQL语句为:
SELECT MAX(JOB_EXECUTION_ID)
FROM BATCH_JOB_EXECUTION
WHERE CREATE_TIME < <ANYTIME>;
DELETE FROM BATCH_JOB_EXECUTION_PARAMS
WHERE JOB_EXECUTION_ID <= <MAX_JOB_EXECUTION_ID>;
解释是:
id | 选择类型 | 桌子 | 分区 | 类型 | 可能的键 | 键 | key_len | 参考 | 行 | 过滤 | 额外 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 删除 | BATCH_JOB_EXECUTION_PARAMS | 空 | 全部 | JOB_EXEC_PARAMS_FK | 空 | 空 | 空 | 10062 | 100 | 使用地点 |
如何优化SQL来解决表锁问题? 如果表没有索引,我不知道有什么方法可以防止表锁定发生。
致以诚挚的问候...
您可以尝试使用此语句进行删除。
DELETE BATCH_JOB_EXECUTION_PARMS
FROM BATCH_JOB_EXECUTION_PARMS
JOIN BATCH_JOB_EXECUTION
ON BATCH_JOB_EXECUTION.JOB_EXECUTION_ID = BATCH_JOB_EXECUTION_PARMS.JOB_EXECUTION_ID
WHERE BATCH_JOB_EXECUTION.CREATE_TIME < <ANYTIME>
LIMIT 100;
这将从 PARMS 表中删除最多 1000 行与您提到的过期条件匹配的行。然后,重复此语句,直到没有删除任何行。
为什么这会起作用?它限制了删除事务中要处理的行数,这反过来又可能限制表锁定的时间。
根据 Spring Batch 文档,我发现
BATCH_JOB_EXECUTION.CREATE_TIME
和 BATCH_JOB_EXECUTION_PARMS.JOB_EXECUTION_ID
列已经有索引。这很好,因为这些是有助于您操作的索引。但这与您向我们展示的表格定义不一致。
如果您的
<ANYTIME>
已经很久了,数据库的相关行没有再发生任何事情,您可以尝试使用所谓的 脏读 来进行删除。在您的陈述之前加上
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
获得这个(有点冒险的)优化;它通过忽略数据库其他用户的事务来节省数据库开销。 (你不能用其他人的钱和其他交易敏感数据来做到这一点。)