MySQL 针对 LOAD DATA INFILE 的优化

标签 mysql optimization myisam load-data-infile

我到处都看到程序员在讨论如何优化最快的 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/

相关文章:

html - 根据 div 图像所在的位置访问不同的图像副本

mysql - InnoDB 与 MyIsam 在频繁排序的 MySQL 5.5 表上的比较

MYSQL MyIsaM 如何Join 2语句select + select count

mysql - 如何获得正确的最小值和最大值

php - 如何从生成的 php 表中获取 id 的值并删除具有该 id 的行

performance - WordPress 网站上的高延迟为 4-6 秒

Clang 与 1 优化的倒数

innoDB 表的 MySQL 全文搜索解决方法

php - 您可以将使用 imagecopyresized() 的图像保存到 MySQL 吗?

php - 在 PHP/MySQL 中隐藏过去的事情