MySQL 针对没有索引的表优化 SQL

问题描述 投票:0回答:1

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来解决表锁问题? 如果表没有索引,我不知道有什么方法可以防止表锁定发生。

致以诚挚的问候...

mysql query-optimization sql-delete
1个回答
0
投票

您可以尝试使用此语句进行删除。

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;

获得这个(有点冒险的)优化;它通过忽略数据库其他用户的事务来节省数据库开销。 (你不能用其他人的钱和其他交易敏感数据来做到这一点。)

© www.soinside.com 2019 - 2024. All rights reserved.