我可以在delete查询中使用set lock\u timeout吗?

dpiehjr4  于 2021-06-19  发布在  Mysql
关注(0)|答案(1)|浏览(308)

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

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

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

pinkon5k

pinkon5k1#

在一个大表上执行像您这样的批量操作可能非常耗时。为什么?
服务器可能很难找到正确的行。
单个查询(在innodb中)具有事务语义。也就是说,如果服务器的任何部分出现故障,服务器必须能够回滚整个操作。这意味着服务器必须存储足够的数据来恢复所有删除的行,直到删除操作完成。这样做会使服务器很难工作。
应用程序的其他部分可能同时访问同一个表。如果是这样,他们等着轮到他们,你的系统就会阻塞。
如何解决这个问题。
确保列上有一个名为 DATE 因此服务器可以高效地找到正确的行。
如果应用程序的其他部分查询数据库,请将此语句放在select语句之前。 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; . 这告诉查询它可以继续进行,即使它可能得到一个即将被删除的行。
最佳选择:批量删除。请执行以下操作:

DELETE * FROM TABLE_NAME WHERE DATE >= (STARTDATE) AND DATE <= (EndDate) LIMIT 1000;

并重复delete操作,直到它处理零行。它使用多个事务,同时将每个事务保持在合理的大小,这样服务器就不会被它们阻塞。
这类事情可以在java中用一个类似于伪代码的循环来完成。

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

相关问题