我在生产数据库中运行删除少量记录时出现了一些问题,这些记录包含大量记录。
我的表是:
会员:8m记录
Member_child:62m记录
我的应用程序需要删除某个提交(sub_id)值成员的所有子记录,因此尝试运行查询:
delete from member_child where member_id in (select m1.id from member m1 where m1.sub_id=xxx)
我提交的提交在子表中有大约500条记录。
删除语句大约需要6分钟才能完成,这不是很好的用户体验。
当此查询运行时,我连接另一个MySQL连接并运行“显示ENGINE INNODB ENGINE \ G;'我可以看到查询在5m +记录上创建了锁:
---TRANSACTION 0 48901, ACTIVE 233 sec, process no 32526, OS thread id
139811386337024 starting index read, thread declared inside InnoDB 269
mysql tables in use 2, locked 2
488961 lock struct(s), heap size 47413232, 5052181 row lock(s)
MySQL thread id 2, query id 140 localhost iconnect preparing
delete from member_child where member_id in (select m1.id from
member m1 where m1.sub_id=12345)
我相信我的索引是正确的。关于我还能尝试什么的任何建议?
这是在linux上运行的MySql v5.1.73。
我的交易隔离'是READ-COMMITTED(必须从默认设置更改此设置,以便不同的提交的并发查询可以同时运行,而没有一个查询失败,并且锁定超时异常)和'innodb_buffer_pool_size' = 1G。
答案 0 :(得分:0)
尝试使用内部联接而不是in子句
并确保memeber表上的复合索引为(sub_id,id)
delete from member_child mc
inner join member m1 on mc.member_id = m1.id and m1.sub_id = xxx
答案 1 :(得分:0)
您需要索引。我倾向于把它写成:
delete mc
from member_child mc join
member m
on mc.member_id = m.id and m.sub_id = xxx;
然后您需要member(sub_id, id)
和member_child(member_id)
上的索引。