负载数据INFILE的

时间:2017-05-28 23:21:52

标签: mysql optimization myisam load-data-infile

我看到所有程序员都在为最快的LOAD DATA INFILE插入进行优化。但他们从未解释过他们的价值观选择等,优化取决于环境以及实际的实际需求。

所以,想请一些关于我的mysql配置文件中最好的值的解释,以便尽可能快地插入。

我的配置,英特尔双核@ 3.30 GHz,4Gb DDR4内存(windows7说" 2.16Gb可用"因为保留内存)。

我的backup.csv文件是纯文本大约5亿条,所以它的文件大小就像这个schem一样巨大(但是十六进制字符串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;

正如您所看到的,命令使用LOAD DATA INFILE采用纯文本值,将它们转换为HEX(两者都是十六进制哈希,所以......)

我听说过缓冲区大小等,以及MySQL配置文件中的所有值。我应该改变什么,最好的价值是什么? 正如您所看到的,我锁定了桌子,并且还禁用了加速它的键。

我还阅读了文档:

 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

编辑:忘了告诉,一切都是localhost。

2 个答案:

答案 0 :(得分:1)

我很确定这是验证,而不是verification.MYD或其他两个。 .MYD是数据,.MYI是索引,.frm是架构。

琴弦有多长?是十六进制?如果是32位十六进制数字,那么您不希望BINARY(16)输出UNHEX吗?

该过程的很长一段时间可能是ENABLE KEYS,何时构建索引。在SHOW PROCESSLIST;运行时执行 - 如果它说“使用密钥缓冲区”,请将其删除,这将需要永远。如果说的是“通过修复构建”,那么它很好 - 它正在排序,然后有效地加载索引。

在开始此过程之前,您可以通过设置myisam_data_pointer_size=5来节省5GB的磁盘空间。似乎还有myisam_index_pointer_size,但它可能默认为5,这对您的情况可能是正确的。 (我在2004年左右在4.0版本上遇到过那个设置;但是再也没有。)

我不认为key_buffer_size在加载和索引期间会很重要 - 因为你真的希望它不使用key_buffer。不要将它设置得太高以至于RAM耗尽。为了表现,交换可怕

答案 1 :(得分:1)

所以,我最终设法插入了超过30亿条目的500GB数据库,大概是5个小时。

我尝试了很多方法,在重建Primary Index时我遇到了这个错误ERROR 1034 (HY000): Duplicate key 1 for record at 2229897540 against new record at 533925080

我现在将解释如何完成插入:

  • 我将.csv文件排序为GNU CoreUtils : sort.exe(我在Windows上)请记住这样做,你需要1.5倍的csv文件作为可用空间,用于临时文件。 (所以计算.csv文件,最终的2.5倍)
  • 您可以使用索引和所有内容创建表。
  • 执行mysqladmin flush-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将通过尝试修复它们来忽略可能的重复错误(而不是在等待数小时后停止插入!)

  • 执行mysqladmin flush-tables -u a_db_user -p

我完成了!

  • 如果.csv文件位于数据库之外的另一个驱动器上,并且sort操作相同,我注意到速度大大提升,将临时文件放在另一个驱动器中。 (读/写速度不是两个数据都在同一个地方)

此消息的来源再次出现在:Credits here to this solution