MySQL插入性能优化(转)
对于一些数据量较大的系统,数据库面临的问题除了查询效率低下,还有就是数据入库时间长。特别像报表系统,每天花费在数据导入上的时间可能会长达几个小时或十几个小时之久。因此,优化数据库插入性能是很有意义的。
经过对MySQL innodb的一些性能测试,发现一些可以提高insert效率的方法,供大家参考参考。
1. 一条SQL语句插入多条数据。
常用的插入语句如:
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`)
VALUES ('', 'userid_0', 'content_0', 0);
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`)
VALUES ('', 'userid_1', 'content_1', 1);
修改成:
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`)
VALUES ('', 'userid_0', 'content_0', 0), ('', '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 ('', 'userid_0', 'content_0', 0);
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`)
VALUES ('', 'userid_1', 'content_1', 1);
...
COMMIT;
使用事务可以提高数据的插入效率,这是因为进行一个INSERT操作时,MySQL内部会建立一个事务,在事务内才进行真正插入处理操作。通过使用事务可以减少创建事务的消耗,所有插入都在执行后才进行提交操作。
这里也提供了测试对比,分别是不使用事务与使用事务在记录数为1百、1千、1万的情况。
3. 数据有序插入。
数据有序的插入是指插入记录在主键上是有序排列,例如datetime是记录的主键:
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`)
VALUES ('', 'userid_1', 'content_1', 1);
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`)
VALUES ('', 'userid_0', 'content_0', 0);
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`)
VALUES ('', 'userid_2', 'content_2',2);
修改成:
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`)
VALUES ('', 'userid_0', 'content_0', 0);
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`)
VALUES ('', 'userid_1', 'content_1', 1);
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`)
VALUES ('', '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插入性能优化(转)的更多相关文章
- MySQL插入性能优化
目录 MySQL插入性能优化 代码优化 values 多个 一个事务 插入字段尽量少,尽量用默认值 关闭 unique_checks bulk_insert_buffer_size 配置优化 inno ...
- mysql数据库性能优化(包括SQL,表结构,索引,缓存)
优化目标减少 IO 次数IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑,当 ...
- MySQL查询性能优化(精)
MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...
- Mysql数据库性能优化(一)
参考 http://www.jb51.net/article/82254.htm 今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要 ...
- 170727、MySQL查询性能优化
MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...
- MySQL 数据库性能优化之缓存参数优化
在平时被问及最多的问题就是关于 MySQL 数据库性能优化方面的问题,所以最近打算写一个MySQL数据库性能优化方面的系列文章,希望对初中级 MySQL DBA 以及其他对 MySQL 性能优化感兴趣 ...
- DB-MySQL:MySQL 语句性能优化
ylbtech-DB-MySQL:MySQL 语句性能优化 1.返回顶部 1. MySQL概述1.数据库设计 3范式2.数据库分表分库---会员系统() 水平分割(分页如何查询)MyChar .垂直3 ...
- MySQL“被动”性能优化汇总!
年少不知优化苦,遇坑方知优化难. --村口王大爷 本文内容导图如下: 我之前有很多文章都在讲性能优化的问题,比如下面这些: <switch 的性能提升了 3 倍,我只用了这一招!> < ...
- 1229【MySQL】性能优化之 Index Condition Pushdown
转自http://blog.itpub.net/22664653/viewspace-1210844/ [MySQL]性能优化之 Index Condition Pushdown2014-07-06 ...
随机推荐
- js unicode处理
//岗位详细界面 var str="1.\u000D\u21B52.\u000D\u21B53"; var pad = function() { var tbl = []; ret ...
- 【Java面试题】57 short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
Java规范有这样的规则 [ 1.高位转低位需要强制转换 2.低位转高位自动转. ] short s1 = 1; s1 = s1 + 1;有什么错? 答: i 是int 型 s1 short型 通 ...
- CentOS6.8安装mysql并设置字符集编码
一.安装: 1. 首先以root用户进入系统 2. 输入命令: yum install mysql mysql-server -y 等待安装完成. 3. 启动MySQL,输入命令: /etc/init ...
- CString TCHAR互相转换
CString->TCHAR*的转化可以用函数GetBuffer() // 原型:LPTSTR GetBuffer( int nMinBufLength ); CString str(_T(&q ...
- web开发中的安全问题
web开发中很多东西由前段来负责判断,比如常见的邮箱 电话号码,前端判断到不是一个正确的格式,在你点击提交时候提示你格式填错了,然后不请求后端php,直到你填写正确的格式为止.这种其实可以修改js或者 ...
- 把Excel中的数据转换成Sql语句
假如excel表格中有A.B.C三列数据,希望导入到数据库users表中,相应的字段各自是name,sex,age ,在你的excel表格中添加一列.利用excel的公式自己主动生成sql语句,方法例 ...
- swift学习笔记之—自定义函数的规则说明
原文出自:www.hangge.com 转载请保留原文链接:http://www.hangge.com/blog/cache/detail_517.html 1,无返回值的函数 func test( ...
- NodeJS-002-Expres启动
1.打开app.js文件 2.在module.exports = app;之前输入: app.listen(8100,function(){ console.log("Server Star ...
- laravel 控制器多个方法共用一个路由
直接上代码: Route::get('Index/{action}', function(App\Http\Controllers\IndexController $index, $action){ ...
- UE4.16播放全景视频
全景视频有两种:一种是常见的一帧画面里面包含一张全景图,另外一种是一帧画面里面包含了左眼和右眼两张全景图. 根据种类的不同,选择不同的材质分别对应MAT_Single_Image和MAT_Stereo ...