mysql - 提高 mysql LOAD DATA / mysqlimport 的性能?
问题描述
我CSV
将 15GB(30mio 行)批处理到mysql-8
数据库中。
问题:任务大约需要 20 分钟,吞吐量约为 15-20 MB/s。虽然硬盘能够以 150 MB/s 的速度传输文件。
我有一个 20GB 的 RAM 磁盘,用于保存我的 csv。导入如下:
mysqlimport --user="root" --password="pass" --local --use-threads=8 mytable /tmp/mydata.csv
这LOAD DATA
在引擎盖下使用。我的目标表没有任何索引,但大约有 100 列(我无法更改)。
奇怪的是:我尝试在 中调整几个配置参数/etc/mysql/my.cnf
,但它们并没有带来任何显着的改进:
log_bin=OFF
skip-log-bin
innodb_buffer_pool_size=20G
tmp_table_size=20G
max_heap_table_size=20G
innodb_log_buffer_size=4M
innodb_flush_log_at_trx_commit=2
innodb_doublewrite=0
innodb_autoinc_lock_mode=2
问题:是否LOAD DATA
/mysqlimport
尊重这些配置更改?还是绕过?还是我使用了正确的配置文件?
至少对变量进行选择表明它们已由 mysql 服务器正确加载。例如show variables like 'innodb_doublewrite'
节目OFF
无论如何,我怎样才能进一步提高导入速度?还是我的数据库是瓶颈,没有办法克服 15-20 MB/s 的阈值?
更新:有趣的是,如果我将我的 csv 从硬盘导入 ramdisk,性能几乎相同(只是稍微好一点,但从不超过 25 MB/s)。我还测试了相同数量的行,但只有几 (5) 列。在那里我达到了大约 80 MB/s。很明显,列数是瓶颈?但是为什么更多的列会减慢这个过程呢?
解决方案
这可能是正常的。让我们来看看正在做的事情:
- 正在从 RAM 磁盘读取 csv 文件,因此没有使用 IOP。
- 你在使用 InnoDB 吗?如果是这样,数据将进入 buffer_pool。在那里构建块时,它们被标记为“脏”以最终刷新到磁盘。
- 由于 buffer_pool 很大,但可能没有表那么大,因此在读取完所有数据之前需要刷新一些块。
- 读完所有的数据,表完成后,脏块会逐渐刷新到磁盘。
- 如果您有非唯一索引,它们同样会以延迟方式写入磁盘(参见“更改缓冲”)。change_buffer,默认占用buffer_pool的25%。
结果表有多大?它可能比 csv 文件的 15GB 大得多,甚至更小。
将 csv 文件放入 ram 磁盘需要多少时间?我认为那是浪费时间,应该在执行LOAD DATA
;时从磁盘读取它。I/O 可以重叠。
请SHOW GLOBAL VARIABLES LIKE 'innodb%';
; 还有其他几个可能相关。
更多的
这些太可怕了:
tmp_table_size=20G
max_heap_table_size=20G
如果您有一个复杂的查询,可以在 RAM 中分配 20GB,可能是多次!将它们保持在 RAM 的 1% 以下。
如果将 csv 从硬盘复制到 ram 磁盘运行缓慢,我会怀疑 150 MB/s 的有效性。
如果您每 6 小时加载一次表,并且需要 1/3 小时来执行,我不认为加快它的紧迫性。OTOH,可能有一些值得研究的东西。如果由于表被锁定而导致 20 分钟停机,则可以轻松消除:
CREATE TABLE t LIKE real_table;
LOAD DATA INFILE INTO t ...; -- not blocking anyone
RENAME TABLE real_table TO old, t TO real_table; -- atomic; fast
DROP TABLE old;
推荐阅读
- javascript - 将输入中的数据保存到文件中,以便以后在 JS 中查看
- soapui - 如何在带有excel文件的sql查询中传递soapui参数?
- python - 运行具有相对导入的模块作为 __main__
- nlp - 如何微调 BERT 来总结文章
- java - 无法在 main.java (JavaFX) 中添加 Canvas
- java - 带有@JsonProperty 的通用 JSON 响应
- stormcrawler - Stormcrawler 中的 URL 重定向使该页面的爬网处于错误状态
- json - Vanilla JS (FUN ONE):从字符串“map”访问深埋 JSON 节点的最佳方式
- python - 使用 Python3 itertools 排列:如何指定所有 r > 1
- javascript - jQuery - 在页面之间来回更改时保留表单数据