11

我正在尝试使用 LOAD DATA INFILE(来自 CSV)将大约 12m 条记录批量加载到(本地)mysql 中的 InnoDB 表中,并发现它需要很长时间才能完成。

主键类型是 UUID,并且键在数据文件中未排序。

我已将数据文件拆分为包含 100000 条记录的文件并将其导入为:

mysql -e 'ALTER TABLE customer DISABLE KEYS;'
for file in *.csv
    mysql -e "SET sql_log_bin=0;SET FOREIGN_KEY_CHECKS=0; SET UNIQUE_CHECKS=0;
    SET AUTOCOMMIT=0;LOAD DATA INFILE '${file}' INTO TABLE table 
    FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';  COMMIT"

这对于前几十万条记录工作正常,但随后每次加载的插入时间似乎一直在增长(在我杀死它之前,从每次加载大约 7 秒到大约 2 分钟。)

我在具有 8GB RAM 的机器上运行,并将 InnoDB 参数设置为:

innodb_buffer_pool_size =1024M
innodb_additional_mem_pool_size =512M
innodb_log_file_size = 256M
innodb_log_buffer_size = 256M

我还尝试加载一个包含所有行的单个 CSV,但没有运气 - 这在我杀死它之前运行了超过 2 小时。

还有什么可以加快这个速度,因为这似乎是一个过多的时间来加载 12m 记录?

4

2 回答 2

7

如果您知道数据是“干净的”,那么您可以在导入之前删除受影响表上的索引,然后在完成后重新添加它们。

否则,每条记录都会导致索引重新计算,如果你有一堆索引,这真的会减慢速度。

于 2012-01-09T15:09:10.280 回答
2

总是很难说出导致性能问题的原因是什么,但这是我的 2 美分:作为 uuid 的密钥是随机分布的,这使得维护索引变得困难。原因是密钥按范围存储在文件系统块中,因此随机 uuid 彼此跟随会使操作系统在不利用缓存的情况下对文件系统读取和写入块。我不知道您是否可以更改密钥,但您可以对输入文件中的 uuid 进行排序,看看是否有帮助。仅供参考,为了更好地理解这个问题,我会看一下这篇 博文,也许会阅读这本书mysql high performance它有一个关于 innodb 聚集索引的好章节。祝你好运!

于 2012-01-09T15:18:43.103 回答