`

mysql 如何提高批量导入的速度

 
阅读更多

转载:http://blog.chinaunix.net/uid-25909722-id-4049167.html

 

最近一个项目测试,有几个mysql数据库的表数据记录达到了几十万条,在搭建测试环境 导入 测试数据时,十分慢。
在网上搜索了一下,有下面一些方法可以加快
mysql数据库导入数据的速度:
0. 最快的当然是直接 copy 数据库表的数据文件(版本和平台最好要相同或相似);
1. 设置 innodb_flush_log_at_trx_commit = 0 ,相对于 innodb_flush_log_at_trx_commit = 1 可以十分明显的提升导入速度;
2. 使用 load data local infile 提速明显;
3. 修改参数 bulk_insert_buffer_size, 调大批量插入的缓存;
4. 合并多条 insert 为一条: insert into t values(a,b,c),  (d,e,f) ,,,
5. 手动使用事物;


下面是UC的一篇相关博客文章:
http://tech.uc.cn/?p=634
MySQL批量SQL插入性能优化
对于一些数据量较大的系统,数据库面临的问题除了查询效率低下,还有就是数据入库时间长。特别像报表系统,每天花费在数据导入上的时间可能会长达几个小时或十几个小时之久。因此,优化数据库插入性能是很有意义的。

经过对MySQL innodb的一些性能测试,发现一些可以提高insert效率的方法,供大家参考参考。

1. 一条SQL语句插入多条数据。
常用的插入语句如:
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('0', 'userid_0', 'content_0', 0); 
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('1', 'userid_1', 'content_1', 1);
INSERT
 INTO `insert_table` (`datetime`, `uid`, `content`, `type`)  VALUES ('0', 'userid_0','content_0', 0);
INSERT
 INTO `insert_table` (`datetime`, `uid`, `content`, `type`)  VALUES ('1', 'userid_1','content_1', 1);

修改成:
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('0', 'userid_0', 'content_0', 0), ('1', 'userid_1', 'content_1', 1);
INSERT
 INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('0', 'userid_0','content_0', 0), ('1', 'userid_1', 'content_1', 1);

修改后的插入操作能够提高程序的插入效率。这里第二种SQL执行效率高的主要原因是合并后日志量(MySQL的binlog和innodb的事务让日志) 减少了,降低日志刷盘的数据量和频率,从而提高效率。通过合并SQL语句,同时也能减少SQL语句解析的次数,减少网络传输的IO。
这里提供一些测试对比数据,分别是进行单条数据的导入与转化成一条SQL语句进行导入,分别测试1百、1千、1万条数据记录。

 

 

2. 在事务中进行插入处理。
把插入修改成:
START TRANSACTION; 
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) 
VALUES ('0', 'userid_0', 'content_0', 0); 
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) 
VALUES ('1', 'userid_1', 'content_1', 1); 
... 
COMMIT;

START TRANSACTION
;
INSERT
 INTO `insert_table` (`datetime`, `uid`, `content`, `type`)    
VALUES
 ('0', 'userid_0', 'content_0', 0);
INSERT
 INTO `insert_table` (`datetime`, `uid`, `content`, `type`)   
VALUES ('1', 'userid_1', 'content_1', 1);
...COMMIT;

使用事务可以提高数据的插入效率,这是因为进行一个INSERT操作时,MySQL内部会建立一个事务,在事务内才进行真正插入处理操作。通过使用事务可以减少创建事务的消耗,所有插入都在执行后才进行提交操作。
这里也提供了测试对比,分别是不使用事务与使用事务在记录数为1百、1千、1万的情况。

 

3. 数据有序插入。
数据有序的插入是指插入记录在主键上是有序排列,例如datetime是记录的主键:
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('1', 'userid_1', 'content_1', 1); 
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('0', 'userid_0', 'content_0', 0); 
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('2', 'userid_2', 'content_2',2);
INSERT
 INTO `insert_table` (`datetime`, `uid`, `content`, `type`)  VALUES ('1', 'userid_1','content_1', 1);
INSERT
 INTO `insert_table` (`datetime`, `uid`, `content`, `type`)  VALUES ('0', 'userid_0','content_0', 0);
INSERT
 INTO `insert_table` (`datetime`, `uid`, `content`, `type`)  VALUES ('2', 'userid_2','content_2',2);

修改成:
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('0', 'userid_0', 'content_0', 0); 
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('1', 'userid_1', 'content_1', 1); 
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('2', 'userid_2', 'content_2',2);
INSERT
 INTO `insert_table` (`datetime`, `uid`, `content`, `type`)  VALUES ('0', 'userid_0','content_0', 0);
INSERT
 INTO `insert_table` (`datetime`, `uid`, `content`, `type`)  VALUES ('1', 'userid_1','content_1', 1);
INSERT
 INTO `insert_table` (`datetime`, `uid`, `content`, `type`)  VALUES ('2', 'userid_2','content_2',2);

由于数据库插入时,需要维护索引数据,无序的记录会增大维护索引的成本。我们可以参照innodb使用的B+tree索引,如果每次插入记录都在索引的最 后面,索引的定位效率很高,并且对索引调整较小;如果插入的记录在索引中间,需要B+tree进行分裂合并等处理,会消耗比较多计算资源,并且插入记录的 索引定位效率会下降,数据量较大时会有频繁的磁盘操作。
下面提供随机数据与顺序数据的性能对比,分别是记录为1百、1千、1万、10万、100万。

从测试结果来看,该优化方法的性能有所提高,但是提高并不是很明显。

 

性能综合测试:
这里提供了同时使用上面三种方法进行INSERT效率优化的测试。

从测试结果可以看到,合并数据+事务的方法在较小数据量时,性能提高是很明显的,数据量较大时(1千万以上),性能会急剧下降,这是由于此时数据量超过了 innodb_buffer的容量,每次定位索引涉及较多的磁盘读写操作,性能下降较快。而使用合并数据+事务+有序数据的方式在数据量达到千万级以上表 现依旧是良好,在数据量较大时,有序数据索引定位较为方便,不需要频繁对磁盘进行读写操作,所以可以维持较高的性能。

 

注意事项:
1. SQL语句是有长度限制,在进行数据合并在同一SQL中务必不能超过SQL长度限制,通过max_allowed_packet配置可以修改,默认是1M,测试时修改为8M。
2. 事务需要控制大小,事务太大可能会影响执行的效率。MySQL有innodb_log_buffer_size配置项,超过这个值会把innodb的数据刷到磁盘中,这时,效率会有所下降。所以比较好的做法是,在数据达到这个这个值前进行事务提交。

 

  • 大小: 15.2 KB
  • 大小: 15.7 KB
  • 大小: 24.6 KB
  • 大小: 40.5 KB
分享到:
评论

相关推荐

    python工具-excel批量导入mysql (几千万数据半小时可搞定)

    本篇文章将详细讲解如何利用Python工具实现Excel数据的批量导入到MySQL数据库,以及如何优化这一过程,使得几千万的数据能够在半小时内完成导入。 首先,我们需要了解Python中用于操作Excel的主要库——pandas。...

    向MySQL批量导入文本文件

    本篇文章将详细讲解如何向MySQL批量导入文本文件,以便于快速有效地处理大量数据。 首先,理解文本文件导入的基本原理。在MySQL中,最常用的文本格式是CSV(Comma Separated Values,逗号分隔值)或TSV(Tab ...

    照片批量导入导出

    批量导入可以大大提高效率,尤其当需要一次性处理大量照片时。 4. **批量导出**:导出照片通常通过查询数据库并把结果导出为文件格式完成,如CSV、XML或直接导出为图片文件。Oracle提供Data Pump(expdp/impdp)...

    mysql中将一个表数据批量导入另一表.rar

    - **性能优化**:对于大表,可以考虑分批导入,或者对目标表进行临时的索引禁用,以提高导入速度。 - **权限检查**:确保用户有足够的权限执行这些操作,如INSERT、SELECT等。 - **日志监控**:在执行过程中,监控...

    图片批量导入oracle数据库

    将多张图片的插入操作打包成一个批次,然后一次性提交,这样可以减少与数据库的交互次数,提高导入速度。 6. **错误处理和资源关闭**:确保在发生异常时正确地回滚事务,并在操作完成后关闭数据库连接和文件输入流...

    excel批量导入数据库

    3. **批量导入原理**:批量导入通常通过SQL语句(如`LOAD DATA INFILE`在MySQL中,或`BULK INSERT`在SQL Server中)或者编程语言接口(如Java的JDBC,Python的pandas库等)实现。这些方法可以一次性处理大量记录,比...

    neo4j批量数据导入

    6. **性能优化**:批量导入时,可以考虑调整Neo4j的配置参数,如增大堆内存(`-Xmx`)、开启持久化缓存(`dbms.memory.pagecache.size`)等,以提升导入速度。 7. **数据验证**:在导入后,可能需要进行数据一致性...

    批量导入数据,大数据导入

    批量导入可以显著提高效率,避免逐条插入数据的低效。SQL(Structured Query Language)是用于管理关系数据库的标准语言,提供了多种批量导入数据的方法。 1. **使用INSERT语句**:这是最基础的方式,但当数据量大...

    数据批量导入数据库

    2. **性能优化**:根据实际情况调整`BatchSize`参数,找到最佳的批量大小,以提高导入速度。 3. **事务管理**:对于需要保持事务完整性的操作,可以在导入过程中使用事务管理,确保数据的一致性。 #### 五、总结 ...

    文本文件批量导入sql数据库

    本教程将详细介绍如何批量导入文本文件到SQL数据库,以提高效率并优化数据管理。 **批量导入文本文件的重要性** 在处理大量文本数据时,手动逐条输入数据到数据库不仅耗时,而且容易出错。批量导入功能允许我们将...

    10倍以上提高Pentaho Kettle的MySQL写入速度

    标题中的“10倍以上提高Pentaho Kettle的MySQL写入速度”指的是通过优化Pentaho Kettle(也称为Kettle或PDI)的数据处理流程,显著提升了将数据导入到MySQL数据库的速度。Pentaho Kettle是一款强大的ETL(提取、转换...

    java实现批量导入.csv文件到mysql数据库

    java实现批量导入.csv文件到mysql数据库 概述 本文主要介绍了使用Java实现批量导入.csv文件到MySQL数据库的方法。该方法可以快速地将.csv文件中的数据批量导入到数据库中,具有很高的实用价值。 Java实现批量导入...

    优化后的asp批量导入

    以上就是关于"优化后的asp批量导入"的一些核心知识点,优化的目标是提高数据处理速度,减少服务器资源消耗,并确保数据的安全性和完整性。在实际应用中,开发者需要根据具体需求和环境来调整和优化这些方面。

    批量导入数据库中数据

    6. **性能优化**:批量导入数据时,可以调整数据库参数,如增大缓冲区大小、禁用索引以提高速度,然后再重建索引。同时,选择在数据库负载低的时候执行导入操作,可以进一步提升效率。 7. **错误处理**:在导入过程...

    excel信息导入到MySql

    6. 自动化脚本:为了提高效率,可以编写自动化脚本,比如使用Java(J2EE)或其他编程语言,将Excel导入MySQL的过程封装成可重复执行的程序。这样,每次有新的Excel数据时,只需运行脚本即可完成导入。 总结来说,将...

    Redis-PipeLine批量导入.docx

    批量导入数据可以显著提升数据处理速度,尤其在需要初始化大量数据或进行数据迁移时。 批量导入 Redis 数据有两种常见方法: 1. **文本格式批量导入**: 在这种方法中,你可以将所有的 Redis 命令(如 `SET` 和 `...

    sql-数据批量导入

    - **索引策略**:在导入前暂停非聚集索引,导入后再重建,可以提高导入速度。 - **禁用触发器和约束**:暂时禁用数据库的触发器和完整性约束,导入后重新启用,以加快导入速度。 6. **错误处理和验证**: - **预...

    Mysql to Oracle导入导出说明

    7. **性能优化**:如果数据量巨大,可能需要考虑分批导入、并行导入等策略,以提高迁移速度。 总的来说,从MySQL到Oracle的数据迁移涉及多个步骤,包括数据导出、转换、导入以及各种兼容性问题的处理。合理选择工具...

    提高mysql插入数据的速度.pdf

    - 尽管这不在文档中直接提及,但提升磁盘I/O性能对于提高MySQL插入速度同样重要。这包括优化文件系统、使用更快的磁盘或者使用SSD等措施。 9. 使用第三方工具监控和管理: - 使用如Unix的top、Windows的任务管理...

    C#在MySQL大量数据下的高效读取、写入详解

    总结,优化C#与MySQL在大数据场景下的交互,关键在于选择正确的数据访问方式(原生API优于ORM)、充分利用索引、优化数据处理逻辑以及高效地批量插入数据。通过这些策略,可以显著提高处理效率,降低资源消耗,使...

Global site tag (gtag.js) - Google Analytics