java - 我可以在删除查询中使用 SET LOCK_TIMEOUT 吗?

标签 java mysql mamp query-performance

我在办公室使用 MAMP 服务器,其中有一个表存储了大约 75 万 (750 000) 条记录。上传文件时,如果数据已经存在,我们不会因为任何业务逻辑而抛出错误,只需删除文件该时间范围内的那些记录并重新插入文件中的数据即可。但删除时,调试时抛出锁超时异常,文件上传失败。我怎样才能防止这个超时?可以在我们保存在属性文件中的删除查询中使用锁定超时吗?

查询:

 DELETE * FROM TABLE_NAME WHERE DATE >= (STARTDATE) AND DATE <= (EndDate).

例如,必须删除至少 10k 条记录,这些记录可能属于这些日期范围。上面这个查询给出了锁定超时异常。

最佳答案

在大型表上执行像您这样的批量操作可能非常耗时。为什么?

  1. 服务器可能很难找到正确的行。
  2. 单个查询(在 InnoDB 中)具有事务语义。也就是说,如果整个操作的任何部分失败,服务器必须能够回滚整个操作。这意味着服务器必须存储足够的数据来恢复所有已删除的行,直到删除操作完成。这样做会使服务器工作困难。
  3. 应用程序的其他部分可能会同时访问同一个表。如果是这样,他们会等待轮到他们,并且您的系统会阻塞。

如何解决这个问题。

  1. 确保您的列上有一个名为 DATE 的索引,以便服务器可以有效地找到正确的行。
  2. 如果应用程序的其他部分查询数据库,请将此语句放在 SELECT 语句之前。 设置事务隔离级别读取未提交;。这告诉查询即使可能会得到即将被删除的行,它也可以继续进行。
  3. 最佳替代方案:批量删除。这样做:
DELETE * FROM TABLE_NAME WHERE DATE >= (STARTDATE) AND DATE <= (EndDate) LIMIT 1000;

并重复删除操作,直到处理零行。它使用多个事务,同时将每个事务保持在合理的大小,这样服务器就不会被它们阻塞。

在 Java 中,使用像这样的伪代码这样的循环可以最简单地完成此类事情。

 bool done = false;
 while (!done) {
    int rowcount =  execute.Update("Delete Query with LIMIT clause");
    if (rowcount <= 0) done = true;
 }

关于java - 我可以在删除查询中使用 SET LOCK_TIMEOUT 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52914552/

相关文章:

mysql - 用户界面自动完成 : Make multiple ajax requests or load all data at once for a list of locations in a city?

mysql - 加快mysql select查询速度

mysql - MAMP 未连接到本地主机

PHP设置值时的查询问题?

java - 使用 Hibernate 时出现 "java.lang.ClassCastException"错误 (5.4.12)

java - 尝试获取简单属性值时 PropertyUtils.getProperty 失败

java - 方法级别的synchronized可以用Lock代替吗?

mysql - 从csv到mysql的日期转换

mysql - MySql 重启后 : #1452 - Cannot add or update a child row: a foreign key constraint fails

java - Java 中使用原始类型方法的类型不匹配