生成一个巨大的150M行MySQL表

时间:2009-10-19 00:25:14

标签: mysql database

我有一个C程序可以挖掘一个庞大的数据源(20GB的原始文本)并生成大量的INSERT来在简单的空白表(4个整数列和1个主键)上执行。设置为MEMORY表,整个任务在8小时内完成。完成后,表中存在大约1.5亿行。八小时对我来说是一个完全合适的数字。这是一次性交易。

当尝试将MEMORY表转换回MyISAM以便(A)我将为其他进程释放内存并且(B)数据不会被释放时出现问题我重新启动电脑时死亡。

ALTER TABLE memtable ENGINE = MyISAM

我已经让这个ALTER TABLE查询运行了两天以上,而且还没有完成。我现在已经杀了它。

如果我最初将表创建为MyISAM,则写入速度似乎非常差(特别是由于查询需要使用ON DUPLICATE KEY UPDATE技术)。我不能暂时关掉钥匙。如果我去的话,那个表会变得超过1000倍然后我必须重新处理密钥并且基本上在150,000,000,000行上运行GROUP BY。嗯,不。

要实现的一个关键约束:INSERT查询UPDATE记录表中是否存在主键(哈希)。

在尝试严格使用MyISAM时,我的速度达到每秒1,250行。一旦指数增长,我想这个利率会更高。


我在机器上安装了16GB的内存。什么是生成大型表的最佳方法,最终最终成为磁盘上的索引MyISAM表?


澄清:查询(INSERT ... ON DUPLICATE KEY UPDATE val=val+whatever)中有很多次UPDATE。无论如何,这不是原始转储问题。我首先尝试MEMORY表的原因是为了加速每个INSERT发生的所有索引查找和表更改。

2 个答案:

答案 0 :(得分:3)

如果您打算将其设为MyISAM表,为什么首先要在内存中创建它?如果只是为了速度,我认为转换到MyISAM表将会通过在内存中创建它来取消任何速度提升。

你说直接插入“磁盘上”表太慢了(虽然我不确定你当前的方法需要几天才决定它是什么),你可能可以关闭或删除唯一性约束然后使用DELETE查询重新建立唯一性,然后重新启用/添加约束。我在过去导入到INNODB表时使用了这种技术,即使后来删除它也总体上要快得多。

另一种选择可能是创建一个CSV文件而不是INSERT语句,并使用LOAD DATA INFILE将其加载到表中(我相信它比插入更快,但我找不到引用根据您的需要,直接通过CSV storage engine使用它。

答案 1 :(得分:1)

很抱歉继续向你发表评论(可能是最后一篇)。

我刚刚发现this article提供了一个将大表从MyISAM转换为InnoDB的示例,虽然这不是您正在做的事情,但他使用了一个中间内存表并描述了从内存到InnoDB的情况。一种有效的方法 - 在内存中按照InnoDB预期最终订购的方式对表进行排序。如果你没有与MyISAM绑定,那么你可能需要一个“正确”的内存表。