【发布时间】:2014-01-17 07:14:24
【问题描述】:
我有很多数据 - 5000 万行。但由于次优选择,我选择了错误的索引,现在插入需要很长时间(插入 1000 行需要 60 秒)。
CREATE TABLE `slots` (
`customerid` int(11) NOT NULL,
`orderid` int(11) NOT NULL,
`queueid` int(11) NOT NULL AUTO_INCREMENT,
`item_id` int(3) NOT NULL,
`variable1` int(3) NOT NULL,
`variable2` int(3) NOT NULL,
`variable3` int(3) NOT NULL,
`variable4` int(3) NOT NULL,
`variable5` int(3) NOT NULL,
`variable6` int(3) NOT NULL,
`variable7` tinyint(1) NOT NULL,
`variable8` tinyint(1) NOT NULL,
`variable9` tinyint(1) NOT NULL,
PRIMARY KEY (`customerid`,`orderid`,`queueid`),
UNIQUE KEY `queueid` (`queueid`),
KEY `orderid` (`orderid`)
) ENGINE=InnoDB AUTO_INCREMENT=25883472 DEFAULT CHARSET=latin1
我认为这是因为 PRIMARY KEY 是多列的,并且每次插入后都需要重新索引表(因为 customerid 和 orderid 没有以任何升序/降序方式插入,而是在随机位置插入)。如果我在queueid 上有一个自动增量的主键,它会大大加快插入速度吗?
我可以在没有损坏索引的情况下导出表吗?然后用更好的键重新索引它?
我尝试使用 SQL 语句删除键,但花了很长时间,我中断了它。有什么方法可以看到进度吗?如果我不知道我需要多长时间,我不会等待 - 毕竟可能需要几天?
我需要重新索引这个表,因为它最终将有 10 亿行,并且插入性能会更加恶化。
或者也许最好放弃我已经插入的内容并使用适当的索引开始一个新表?并且不用费心重用旧数据?
【问题讨论】:
-
显示您的插入查询。和最后尝试的代码
-
现在插入 PHP 脚本的工作方式如下:获取数据。创建 500-1000 行 INSERT IGNORE 语句(将它们插入到一个“go”中,而不是通过 500-1000 个单独的 INSERT 操作)。执行 INSERT IGNORE 查询。
-
还有几件事要尝试:(1) 使用多行插入添加数据,(2) 在事务中将多个插入一起批处理(例如 1000 个),(3) 以上两者一起。这可能会为您带来一些性能改进。
标签: php mysql sql phpmyadmin innodb