我正在运行MySql 5.0.22并且有一个非常笨重的表,其中包含大约500万行。
某些(但不是所有)行都被另一个表的外键引用。
到目前为止,所有剔除未引用行的尝试都失败了,每次都会导致锁定超时。
将我想要的行复制到备用表也失败了,锁定超时。
可疑的是,即使是一个应该像下面那样立即完成的声明也会因“锁定超时”而失败:
DELETE FROM mytable WHERE uid_pk = 1 LIMIT 1;
......就在这一点上,我已经没有想法了。
编辑:为了它的价值,我一直在我的开发系统上完成这个工作,所以现在我只是在实际使用数据库所以不应该在SQL之外进行任何锁定我是运行
那里的任何MySql专家都有关于如何驯服这个流氓表的建议?
编辑#2:根据要求,表格结构:
CREATE TABLE `tunknowncustomer` (
`UID_PK` int(11) NOT NULL auto_increment,
`UNKNOWNCUSTOMERGUID` varchar(36) NOT NULL,
`CREATIONDATE` datetime NOT NULL,
`EMAIL` varchar(100) default NULL,
`CUSTOMERUID` int(11) default NULL,
PRIMARY KEY (`UID_PK`),
KEY `IUNKNOWCUST_CUID` (`CUSTOMERUID`),
KEY `IUNKNOWCUST_UCGUID` (`UNKNOWNCUSTOMERGUID`),
CONSTRAINT `tunknowncustomer_ibfk_1` FOREIGN KEY (`CUSTOMERUID`) REFERENCES `tcustomer` (`UID_PK`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$
注意,尝试放弃FK也会超时。
答案 0 :(得分:3)
我对innodb表有同样的问题。优化表纠正了它。
答案 1 :(得分:1)
好的,我终于找到了一种方法,可以修剪我的大型InnoDB表中不需要的行!我是这样做的:
整个努力看起来有点像这样:
ALTER TABLE `ep411`.`tunknowncustomer` RENAME TO `ep411`.`tunknowncustomer2`;
......很奇怪,重命名表是唯一可以立即完成的ALTER TABLE命令。
delimiter $$
CREATE TABLE `tunknowncustomer` (
...
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$
...然后重新启动,以防万一我之前失败的尝试可以阻止任何新的工作......
SET AUTOCOMMIT = 0;
delete from tunknowncustomer2 where customeruid is null limit 1000;
delete from tunknowncustomer2 where customeruid is null limit 100000;
commit;
delete from tunknowncustomer2 where customeruid is null limit 1000000;
delete from tunknowncustomer2 where customeruid is null limit 1000000;
commit;
...一旦我每次删除100k,InnoDB的执行时间随着每个成功的命令而下降。我假设InnoDB开始在大扫描上进行预读。执行提交会重置预读数据,因此我将COMMIT间隔为每200万行,直到作业完成。
我通过将剩余的行复制到我的“空”克隆表中,然后删除旧的(重命名的)表来完成任务。
不是一个优雅的解决方案,并没有解决为什么从大表中删除一行甚至失败的原因,但至少我得到了我想要的结果!