我到处都看到程序员在讨论如何优化最快的 LOAD DATA INFILE
插入。但他们从来没有解释太多他们的值(value)观选择等,优化取决于环境,也取决于实际的真实需求。
所以,请解释一下我的 mysql 配置文件中达到最快插入速度的最佳值是什么。
我的配置是 intel 双核 @ 3.30 GHz、4Gb DDR4 RAM(Windows7 由于保留内存而显示“2.16Gb 可用”)。
我的 backup.csv 文件是纯文本,大约有 50 亿个条目,因此它的文件大小高达 500Gb,如下方案(但十六进制字符串 64 长度):
"sdlfkjdlfkjslfjsdlfkjslrtrtykdjf";"dlksfjdrtyrylkfjlskjfssdlkfjslsdkjf"
我的表中只有两个字段,第一个是唯一索引。 ROW-FORMAT 设置为 FIXED 以解决节省空间的问题。出于同样的原因,字段类型设置为 BINARY(32)。
我正在使用 MyISAM 引擎。 (因为innoDB需要更多的空间!)(MySQL版本5.1.41)
这是我现在计划使用的代码:
ALTER TABLE verification DISABLE KEYS;
LOCK TABLES verification WRITE;
LOAD DATA INFILE 'G:\\backup.csv'
IGNORE INTO TABLE verification
FIELDS TERMINATED BY ';' ENCLOSED BY '"' LINES TERMINATED BY '\r\n'
(@myhash, @myverif) SET hash = UNHEX(@myhash), verif = UNHEX(@myverif);
UNLOCK TABLES;
ALTER TABLE verification ENABLE KEYS;
如您所见,命令 use LOAD DATA INFILE
获取纯文本值,将它们转换为十六进制(最终都是十六进制哈希,所以...)
我听说了缓冲区大小等,以及来自 MySQL 配置文件的所有这些值。我应该改变什么,最好的值是什么? 正如您所看到的,我锁定了 table ,并且还禁用了加速它的键。
我还阅读了文档:
myisamchk --keys-used=0 -rq /var/lib/mysql/dbName/tblName
在插入之前执行此操作也会加快速度。但 tblName
到底是什么? (因为我有一个 .frm 文件、一个 .MYD 和一个 .MYI,所以我应该指向哪一个?)
Here are the lasts short hints i did read about optimisation
编辑:忘了告诉,一切都是本地主机。
最佳答案
所以,我终于在大约 5 个小时内成功插入了包含超过 30 亿个条目的 500GB 数据库。
我尝试了很多方法,在重建主索引
时,我遇到了这个错误错误1034(HY000):重复键1用于记录2229897540与新记录533925080
.
我现在将解释我如何完成插入:
- 我使用
GNU CoreUtils : sort.exe
对我的.csv
文件进行排序(我在 Windows 上)请记住这样做,您需要 1.5 倍的免费 csv 文件空间,用于临时文件。 (算上 .csv 文件,最终是 2.5 倍) - 您创建带有索引和所有内容的表。
- 执行
mysqladminlush-tables -u a_db_user -p
- 执行
myisamchk --keys-used=0 -rq/var/lib/mysql/dbName/tblName
插入数据:(不要使用
ALTER TABLE tblname DISABLE KEYS;
!!!)LOCK TABLES verification WRITE; LOAD DATA INFILE 'G:\\backup.csv' IGNORE INTO TABLE verification FIELDS TERMINATED BY ';' ENCLOSED BY '"' LINES TERMINATED BY '\r\n' (@myhash, @myverif) SET hash = UNHEX(@myhash), verif = UNHEX(@myverif); UNLOCK TABLES;
插入数据时,可以通过执行
myisamchk --key_buffer_size=1024M --sort_buffer_size=1024M -rqq/var/lib/mysql/dbName/tblName
来重建索引 (注意-rqq
,加倍q
将通过尝试修复来忽略可能的重复错误(而不是在等待数小时后停止插入!)- 执行
mysqladminlush-tables -u a_db_user -p
我就完成了!
- 我注意到,如果
.csv
文件位于数据库之外的另一个驱动器上,则速度会大幅提升,对于sort
操作也是如此,将临时文件放入另一个驱动器中。 (读/写速度不是两个数据都在同一个地方)
这个来源再次在这里:Credits here to this solution
关于MySQL 针对 LOAD DATA INFILE 的优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44232932/