【发布时间】:2012-12-21 09:04:14
【问题描述】:
我的这张表有超过 700 万行,我正在 LOAD DATA LOCAL INFILE'ing 一次将 50 万行的更多数据放入其中。前几次很快,但这次添加花费的时间越来越长,可能是由于索引开销:
CREATE TABLE `orthograph_ests` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`digest` char(32) NOT NULL,
`taxid` int(10) unsigned NOT NULL,
`date` int(10) unsigned DEFAULT NULL,
`header` varchar(255) NOT NULL,
`sequence` mediumblob,
PRIMARY KEY (`id`),
UNIQUE KEY `digest` (`digest`),
KEY `taxid` (`taxid`),
KEY `header` (`header`)
) ENGINE=InnoDB AUTO_INCREMENT=12134266 DEFAULT CHARSET=latin1
我正在开发一个将在预先存在的数据库上运行的应用程序。我很可能无法控制服务器变量,除非我强制更改它们(我不希望这样做),所以恐怕像 these 这样的建议用途有限。
我已经读过,最小化此表上的键会有所帮助。但是,我需要这些键用于以后的查询。我猜如果我删除并重新创建它们也需要很长时间,但我还没有测试过。我还读到,尤其是 UNIQUE 约束会使插入速度变慢。 digest 列将采用 必须 唯一的 SHA256 摘要,我无法确保没有冲突(我知道,这不太可能,但可能)。
按照here 的建议,分区会有所帮助吗?我可以改进索引,例如,通过限制 digest 列上的键长度?我应该换成MyISAM,它在交易期间支持DISABLE KEYS吗?我还能做些什么来提高LOAD DATA 的性能?
编辑:
大插入后,此表仅用于SELECTs,不再写入。这种大型加载主要是一次完成的操作,但是在完成之前需要上传大约 1,000 个数据集(每 0.5M 行)。
我将使用摘要来查找行,这就是我为该列编制索引的原因。如果发生冲突,则不应上传该单独的行。
将sequence blob 放在外部文件系统中可能不是一个可行的选择,因为我不能轻易地将文件系统更改强加给用户。
【问题讨论】:
-
"我知道,不太可能,但可能" 您的服务器更有可能发生随机内存位翻转。您无需针对 SHA-256 冲突进行规划。
-
请澄清一些事情:这个表是用作参考表,还是你会做改变它的生产交易?您会定期将半兆行的新数据加载到其中,还是加载一次完成的操作?您的摘要列的目的是什么——您将使用摘要来查找生产中的行吗?如果您的摘要确实遇到哈希冲突,您的恢复计划是什么?您是否考虑过将您的序列列(您的 blob)放在外部文件系统中?
-
@OllieJones:感谢您的评论。编辑了问题。
-
@usr: 感谢您的评论 :)
-
无论您进行何种微优化,除非您可以访问服务器配置或将机械 HDD 子系统替换为更快的子系统 - 没有任何帮助。人们通常会忘记计算机不是神奇的独角兽,使用关系数据库的应用程序通常很慢,因为数据持久性设备的 IOPS 层会立即受到影响。
标签: mysql performance innodb load-data-infile