Sql 从包含数百万条记录的表中删除
我试图找到一种方法,在一个包含数百万条记录的InnoDB表上执行条件删除,而不锁定它(因此不会关闭网站)Sql 从包含数百万条记录的表中删除,sql,mysql,Sql,Mysql,我试图找到一种方法,在一个包含数百万条记录的InnoDB表上执行条件删除,而不锁定它(因此不会关闭网站) 我试图在mysql.com上查找信息,但没有结果。关于如何继续的任何提示?如果它适合您的应用程序,那么您可以限制要删除的行数,并设置一个cronjob以重复删除。例如: DELETE FROM tab WHERE .. LIMIT 1000 我发现在类似的情况下,这是一个很好的折衷方案。我认为不锁定就删除是不可能的。也就是说,我不认为锁定要删除的记录是一个问题。锁定其他行将是一个问题 我在
我试图在mysql.com上查找信息,但没有结果。关于如何继续的任何提示?如果它适合您的应用程序,那么您可以限制要删除的行数,并设置一个cronjob以重复删除。例如:
DELETE FROM tab WHERE .. LIMIT 1000
我发现在类似的情况下,这是一个很好的折衷方案。我认为不锁定就删除是不可能的。也就是说,我不认为锁定要删除的记录是一个问题。锁定其他行将是一个问题 我在这里找到了一些关于这个主题的信息: 我的建议是,尝试执行一百万次单行删除。我认为,如果您在一个事务中完成所有这些操作,那么性能应该不会受到太大的影响。所以你会得到这样的结果:
START TRANSACTION;
DELETE FROM tab WHERE id = 1;
..
..
DELETE FROM tab WHERE id = x;
COMMIT;
您可以通过执行以下操作来生成所需的stations
SELECT CONCAT('DELETE FROM tab WHERE id = ', id)
FROM tab
WHERE <some intricate condition that selects the set you want to delete>
选择CONCAT('DELETE FROM tab WHERE id=',id)
从选项卡
哪里
因此,与此方法相比,该方法的优势在于:
DELETE FROM tab
WHERE <some intricate condition that selects the set you want to delete>
从选项卡中删除
哪里
在第一种方法中,您只锁定要删除的记录,而在第二种方法中,您可能会面临锁定与要删除的行在同一范围内的其他记录的风险。我使用过程来删除
create procedure delete_last_year_data()
begin
DECLARE del_row varchar(255);
DECLARE done INT DEFAULT 0;
declare del_rows cursor for select CONCAT('DELETE FROM table_name WHERE id = ', id)
from table_name
where created_time < '2018-01-01 00:00:00';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
open del_rows;
repeat
fetch del_rows into del_row;
if not done
then
set @del = del_row;
prepare stmt from @del;
execute stmt;
DEALLOCATE PREPARE stmt;
end if;
until done end repeat;
close del_rows;
create procedure delete\u last\u year\u data()
开始
声明del_row varchar(255);
声明完成INT默认值为0;
声明select CONCAT的del_行光标('DELETE FROM table_name WHERE id=',id)
从表\u名称
创建时间为<'2018-01-01 00:00:00';
为未找到的集合声明CONTINUE处理程序done=1;
打开delu行;
重复
将删除行提取到删除行中;
如果不这样做
然后
设置@del=del_行;
从@del准备stmt;
执行stmt;
解除分配准备stmt;
如果结束;
直到完成为止重复;
关闭Delu行;
end/此表上有很多索引吗?为将处理条件的列编制索引。然后在站点的流量较低时执行删除操作(可能是@night)。另请参阅其中提到的间隙锁定。我认为这种方法的问题是,在隔离集合后评估限制。因此,应用了
其中的,这可能会锁定恰好与要删除的行在同一范围内的行。然后只删除有限数量的记录,这一事实不会改变记录已被锁定的事实。这种方法所做的是保持事务大小较小,这也是很好的。但据我所知,这并不能防止假锁。@Roland:你可能是对的。此解决方案可能并不理想,但在实践中效果很好(有限删除速度很快,因此锁会在很短的时间间隔内保持,限制参数可以调整到实际数据)。在使用这种方法之前,我做了一些基准测试,所有有限删除的累积时间比单个非有限删除完成的时间要短(但此时,它使用了MySQL 3.x和MyISAM表)。它仍然可以工作,但在当前MySQL和InnoDB表上进行基准测试将为细节带来一些启发。是的,我认为可以肯定地说,您描述的场景,与同时具有多版本并发控制和行级锁定功能的InnoDB引擎相比,该产品9年以上旧版本上的表锁定MyISAM引擎可能确实有所不同:p+1,有希望的解决方案!你曾经在实践中使用过这种方法吗?@frunsi:我承认我没有。通常,我不会对删除一百万行有太大的问题,但我管理的系统不会同时受到许多用户的攻击。