批量操作进阶:百万行级数据导入的性能极限
关键词:批量导入;LOAD DATA;分区表;并行导入;MySQL
大家好,我是小耶,写功课只是为了我踩过的坑,你们别再踩了!
上周讲了批量插入一万行的优化方法,有朋友问:百万行怎么办?确实,数据量再上一个台阶,之前的多行INSERT和LOAD DATA又会碰到新瓶颈。今天分享四个进阶技巧。
1 名词解释
- 分区表:将一张大表按某个键(如日期)拆分成多个物理分区,查询时可只扫描相关分区,导入时数据自动落入对应分区,减少锁竞争。
- 禁用索引:导入前关闭索引维护(
ALTER TABLE t DISABLE KEYS),导入后重建(ENABLE KEYS),可大幅提升写入速度。 - 并行导入:将数据文件拆分成多份,同时运行多个导入进程,利用多核CPU和磁盘并行能力。
- 批量加载工具:某些数据库自带专用导入工具(如MySQL的
mysqlimport),比通用LOAD DATA更高效。
2 实际运用
2.1 分区表
按日期范围分区示例:
CREATE TABLE orders ( id INT, order_date DATE, amount DECIMAL(10,2) ) PARTITION BY RANGE (YEAR(order_date)) ( PARTITION p2022 VALUES LESS THAN (2023), PARTITION p2023 VALUES LESS THAN (2024), PARTITION p2024 VALUES LESS THAN (2025) );导入时数据自动落入对应分区,减少锁竞争。
2.2 禁用索引
ALTER TABLE orders DISABLE KEYS; -- 执行批量导入(如 LOAD DATA) ALTER TABLE orders ENABLE KEYS;注意:DISABLE KEYS对非唯一索引有效,唯一索引无法禁用。
2.3 并行导入
将1000万行CSV拆成10个100万行的文件,同时运行10个LOAD DATA会话。示例(shell脚本):
for i in {1..10}; do mysql -e "LOAD DATA LOCAL INFILE 'data_$i.csv' INTO TABLE orders" & done wait需确保主键不冲突(如使用不同的id范围)。
2.4 专用工具:金仓kdb_load
金仓数据库(KingbaseES)提供的kdb_load工具,用法类似LOAD DATA,但针对大数据量做了更深度的优化,支持自动拆分、并行加载。
kdb_load -h localhost -d mydb -U myuser -p 54321 -c data.csv -t mytable主要参数:
-h/-p:数据库主机和端口-d:数据库名-U:用户名-c:源数据文件-t:目标表名
相比通用LOAD DATA,kdb_load在处理100万行以上的数据时,速度可以再快一截,尤其适合批量数据入仓和跨库迁移场景。
3 实测数据(100万行)
| 方法 | 耗时 | 说明 |
|---|---|---|
| 多行INSERT(1000行/批) | 25秒 | 默认配置 |
| LOAD DATA | 8秒 | 基础 |
| 禁用索引 + LOAD DATA | 4秒 | 索引重建额外+2秒 |
| 并行LOAD DATA(4线程) | 1.2秒 | 需拆分文件 |
金仓kdb_load | <1秒 | 专用工具加速更明显 |
4 价值总结
- 分区表、禁用索引、并行导入、专用工具这四招,足以把百万行导入从分钟级压到秒级。
- 不同方法对应不同量级:十万级可用多行INSERT + LOAD DATA,百万级必须上并行 + 禁用索引,千万级以上建议直接用
kdb_load类专用工具。 - 实际落地时,可以先小数据量压测,再按实际耗时决定要不要开并行、要不要上专用工具。
小耶在手,SQL不愁。
还有什么想了解的,欢迎留言!小耶一定知无不言言无不尽……我们下次见~
参考文献
[1] MySQL官方文档:INSERT Statement Optimization
[2] MySQL官方文档:LOAD DATA Statement
[3] 金仓数据库管理员指南:kdb_load 并行加载工具
