【问题标题】:Can I use SET LOCK_TIMEOUT in delete query?我可以在删除查询中使用 SET LOCK_TIMEOUT 吗?
【发布时间】:2018-10-21 10:56:24
【问题描述】:

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

查询:

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

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

【问题讨论】:

  • 你上传的是什么文件?一个 sql,csv?
  • 在此查看:CREATE INDEX
  • Here 是加速大DELETEs 的几种方法。
  • @Rcordoval 一个 CSV 文件。

标签: java mysql mamp query-performance


【解决方案1】:

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

  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;
 }

【讨论】:

  • @OJones 感谢您的帮助。我可以循环遍历要删除的数据的大小,然后在循环中删除数据吗?我的代码是:首先我点击表格并获取该范围内的数据大小。然后我执行这段代码。 int count = list.size(); for(int i=1;i
  • 您当然可以使用您提到的循环。但是你让它变得比它需要的更复杂。查看我的编辑。
  • 非常感谢您的帮助。需要更多帮助。如果我有 5k 条记录的列表,如何执行批量插入以提高插入速度并加载 sql?我在休眠中使用实体管理器插入 sql DB。
  • 目前我插入正常,插入这么多记录需要一段时间。我写了这样的代码: for(Employee object : EmployeeList) { em.persist(object); }。你能告诉我比这更快的方法吗?
  • 有很多关于如何使用 Java、JDBC 和 MySQL 高效插入多行的资料。 stackoverflow.com/questions/4355046/… 就是一个例子。或者您可以编写多行插入语句。 stackoverflow.com/questions/34447305/… 或者你可以使用LOAD DATA INFILE
猜你喜欢
  • 1970-01-01
  • 2011-11-28
  • 1970-01-01
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 2011-03-08
  • 1970-01-01
  • 2020-03-03
相关资源
最近更新 更多