原文:http://mp.weixin.qq.com/s?__biz=MzA5MzY4NTQwMA==&mid=403182899&idx=1&sn=74edf28b0bd29f78f91d02785f34bdeb&scene=23&srcid=0321RBoPB5dOfm3vEQnACMLE#rd

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),
('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;

使用事务可以提高数据的插入效率,这是因为进行一个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
('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的数据刷到磁盘中,这时,效率会有所下降。所以比较好的做法是,在数据达到这个这个值前进行事务提交。

【转】MySQL批量SQL插入各种性能优化的更多相关文章

  1. MySQL批量SQL插入各种性能优化

    对于一些数据量较大的系统.数据库面临的问题除了查询效率低下,还有就是数据入库时间长.特别像报表系统,每天花费在数据导入上的时间可能会长达几个小时或十几个小时之久.因此.优化数据库插入性能是非常有意义的 ...

  2. 深入MySQL(四):MySQL的SQL查询语句性能优化概述

    关于SQL查询语句的优化,有一些一般的优化步骤,本节就介绍一下通用的优化步骤. 一条查询语句是如何执行的 首先,我们如果要明白一条查询语句所运行的过程,这样我们才能针对过程去进行优化. 参考我之前画的 ...

  3. MySQL批量SQL插入性能优化

    对于一些数据量较大的系统,数据库面临的问题除了查询效率低下,还有就是数据入库时间长.特别像报表系统,每天花费在数据导入上的时间可能会长达几个小时或十几个小时之久.因此,优化数据库插入性能是很有意义的. ...

  4. mysql批量sql插入优化

    对于一些数据量较大的系统,数据库面临的问题除了查询效率低下,还有就是数据入库时间长.特别像报表系统,每天花费在数据导入上的时间可能会长达几个小时或十几个小时之久.因此,优化数据库插入性能是很有意义的. ...

  5. 老李分享:MySql的insert语句的性能优化方案

    老李分享:MySql的insert语句的性能优化方案   性能优化一直是测试人员比较感兴趣的内容,poptest在培训学员的时候也加大了性能测试调优的方面的内容,而性能优化需要经验的积累,经验的积累依 ...

  6. Mysql数据库调优和性能优化的21条最佳实践

    Mysql数据库调优和性能优化的21条最佳实践 1. 简介 在Web应用程序体系架构中,数据持久层(通常是一个关系数据库)是关键的核心部分,它对系统的性能有非常重要的影响.MySQL是目前使用最多的开 ...

  7. SQL点滴22—性能优化没有那么神秘

    原文:SQL点滴22-性能优化没有那么神秘 经常听说SQL Server最难的部分是性能优化,不禁让人感到优化这个工作很神秘,这种事情只有高手才能做.很早的时候我在网上看到一位高手写的博客,介绍了SQ ...

  8. MySQL 5.6&5.7 性能优化 TOP10(转)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/NLOneDay/article/deta ...

  9. SQL SERVER 查询性能优化——分析事务与锁(五)

    SQL SERVER 查询性能优化——分析事务与锁(一) SQL SERVER 查询性能优化——分析事务与锁(二) SQL SERVER 查询性能优化——分析事务与锁(三) 上接SQL SERVER ...

随机推荐

  1. Wave - 花たん 音乐

    Wave 歌手:花たん 所属专辑:Flower 間違えて宇宙終わって(宇宙因为一个错误而终结了) 青信号はいつも通り(通行的灯号一如往常的) 飛んでまた止まって(又再停止传播) また 飛びそうだ(然后 ...

  2. Redis数据类型,以及应用场合

    Redis常用的数据类型为String,Hash,List,Set等,简介如下: String 1.String 常用命令: 除了get.set.incr.decr mget等操作外,Redis还提供 ...

  3. ThinkPHP学习(一)

    下载3.2框架后,解压缩到web目录下面,可以看到初始的目录结构如下: 3.2版本相比之前的版本自带了一个完整的应用目录结构和默认的应用入口文件,开发人员可以在这个基 础之上灵活调整.其中, Appl ...

  4. jQuery-1.9.1源码分析系列(四) 缓存系统

    先前在分析Sizzle的时候分析到Sizzle有自己的缓存机制,点击这里查看.不过Sizzle的缓存只是对内使用的(内部自己存,自己取).接下来分析jQuery可以对外使用的缓存(可存可取). 首先需 ...

  5. 自定义iOS 中推送消息 提示框

    看到标题你可能会觉得奇怪 推送消息提示框不是系统自己弹出来的吗? 为什么还要自己自定义呢? 因为项目需求是这样的:最近需要做 远程推送通知 和一个客服系统 包括店铺客服和官方客服两个模块 如果有新的消 ...

  6. Android 不一样的原生分享

    Android做分享功能百度一下就两种方案,其一是用系统原生的Activity,最终弹出一个对话框,下面这种的还好,像右图的那种就嫌弃了,上面提供的应用也相对杂,还记得有次测试还给鄙人提了个Bug:建 ...

  7. Devexpress GridView 数据格式化显示

    gridView1.CustomColumnDisplayText += gridView1_CustomColumnDisplayText; void gridView1_CustomColumnD ...

  8. asp.net <asp:Content>控件

    <asp:Content ID="Content2" ContentPlaceHolderID="CPH_MainContent" runat=" ...

  9. jquery删除添加输入文本框

    效果体验:http://hovertree.com/texiao/jquery/67/ 效果图: 参考:http://hovertree.com/h/bjaf/traversing_each.htm ...

  10. 基于CkEditor实现.net在线开发之路(1)

    我以前的公司使用office sharepoint designer为界面设计器,嵌套各种自定义控件,进行各种管理软件,工作流的开发,遇到比较复杂的逻辑,则采用本地写类库,生成DLL上传到服务器,通过 ...