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

时间:2018-10-21 10:56:24

标签: java mysql mamp query-performance

我在办公室中使用的是MAMP服务器,我的桌子上存储着约75万(75万)条记录。上载文件时,如果已经存在数据,则不会由于任何业务逻辑而引发错误,只是我们删除文件在该时间范围内的那些记录,然后从文件中重新插入数据。但是在删除时,调试时会抛出锁定超时异常,并且文件无法上传。如何防止此超时?可以在保存在属性文件中的删除查询中使用锁定超时吗?

查询:

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

例如,必须删除至少1万条记录,这些记录可能在这些日期范围内。在此查询上方会给出锁定超时异常。

1 个答案:

答案 0 :(得分:0)

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

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

如何解决此问题。

  1. 确保您的列上有一个名为DATE的索引,以便服务器可以有效地找到正确的行。
  2. 如果应用程序的其他部分查询数据库,请将此语句放在SELECT语句之前。 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;。这就告诉查询,即使它可能很快就会被删除,也可以继续进行。
  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;
 }