导出/导入没有索引的5000万行数据库?

时间:2013-12-30 11:47:32

标签: php mysql sql phpmyadmin innodb

我有很多数据 - 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是多列的,并且每次插入后需要对表进行重新索引(因为customeridorderid没有以任何asccending / descending方式插入,而是随机的地方)。如果我在queueid上有一个自动递增的主键,它会大大加快插入速度吗?

我可以导出没有破坏索引的表吗?然后用更好的密钥重新索引它?

我尝试用SQL语句删除密钥但是花了很长时间我打断了它。有没有办法看到进展?如果我不知道我需要多长时间,我不会等待 - 这可能是几天之后?

我需要重新索引此表,因为它最终会有10亿行,插入性能会恶化甚至更多。

或者最好放弃我已插入的内容并使用适当的索引启动新表?不要重复使用旧数据吗?

3 个答案:

答案 0 :(得分:2)

您可以使用禁用键选项导出表格。

请参阅此链接 https://dba.stackexchange.com/questions/3069/does-mysqldump-export-indices-by-default

答案 1 :(得分:1)

最大的问题是,该表将用于什么?如果唯一的查询将是ITEM_ID上的ORDER_ID或聚合范围,那么您只需要在这些列上使用单独的索引。使QUEUE_ID成为主键(因为自动增量确保唯一而不是null)。请尝试以下方法:

更新:根据下面的OP评论,每个客户可以有多个订单ID,反之亦然,但组合必须是唯一的。 IMO,更容易创建满足唯一约束的卫星表,并使用此slots表中该表的索引。

CREATE TABLE cust_order (
    combo_id int(11) NOT NULL AUTO_INCREMENT,
    customerid int(11) NOT NULL,
    orderid int(11) NOT NULL,
    PRIMARY KEY combo_id,
    INDEX customerid (customerid),
    INDEX orderid (orderid),
    UNIQUE KEY combination (customerid, orderid)
) ENGINE=INNODB;

CREATE TABLE `slots` (
 `combo_id` int(11) NOT NULL,
 `queueid` int(11) NOT NULL AUTO_INCREMENT,
 `item_id` int(3) NOT NULL,
 `variable1` int(3) NOT NULL,
 ...
 ...
 `variable9` tinyint(1) NOT NULL,
 PRIMARY KEY `queueid`,
 INDEX `combo_id` (`combo_id`),
 INDEX `itemid` (`itemid`),
 FOREIGN KEY (combo_id)
   REFERENCES cust_order (combo_id)
) ENGINE=INNODB;

您必须运行两个不同的插入查询。首先,加载组合表,它只处理没有卫星数据的数字索引,它应该非常快。之后,当您插入slots时,通过customerid + orderid查找将非常快,您只需使用combo_id作为外键。

请注意您必须使用InnoDB引擎才能使用外键。

答案 2 :(得分:0)

在phpMyAdmin中,首先使用Operations复制表,但选择“仅结构”。然后在复制的表中,更改结构(删除不需要的索引)。然后从原始表中使用“操作”将其复制到复制的表中,并使用“仅数据”。

如果上次复制操作给您带来麻烦,请仅导出原始表格中的数据(从“自定义”面板中导出并将其导入复制的表格。