我有一个相当大的 InnoDB 表,其中包含大约 1000 万行(并且计数,预计将成为该大小的 20 倍)。每行不是那么大(平均为 131 B),但有时我不得不删除其中的一大块,这需要很长时间。这是表结构:
CREATE TABLE `problematic_table` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`taxid` int(10) unsigned NOT NULL,
`blastdb_path` varchar(255) NOT NULL,
`query` char(32) NOT NULL,
`target` int(10) unsigned NOT NULL,
`score` double NOT NULL,
`evalue` varchar(100) NOT NULL,
`log_evalue` double NOT NULL DEFAULT '-999',
`start` int(10) unsigned DEFAULT NULL,
`end` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `taxid` (`taxid`),
KEY `query` (`query`),
KEY `target` (`target`),
KEY `log_evalue` (`log_evalue`)
) ENGINE=InnoDB AUTO_INCREMENT=7888676 DEFAULT CHARSET=latin1;
从表中删除大块的查询就像这样:
DELETE FROM problematic_table WHERE problematic_table.taxid = '57';
像这样的查询只花了将近一个小时就完成了。我可以想象索引重写开销使这些查询非常慢。
我正在开发一个将在预先存在的数据库上运行的应用程序。我很可能无法控制服务器变量,除非我对它们进行强制性更改(我不希望这样做),所以我担心更改这些的建议没有什么价值。
我已经尝试将INSERT ... SELECT
那些我不想删除到临时表中的行并只是删除其余的行,但是随着删除与保留的比率向保留转移,这不再是一个有用的解决方案.
这是一张将来可能会看到频繁INSERT
的s和SELECT
s,但没有UPDATE
s的表。基本上,它是一个需要不时删除部分内容的日志记录和引用表。
我可以通过限制索引的长度来改进这张表上的索引吗?切换到DISABLE KEYS
在交易期间支持的 MyISAM 会有所帮助吗?我还能尝试什么来提高DELETE
性能?
编辑:一种这样的删除将是大约一百万行。