这篇文章主要讲解了“大数据量的情况下MySQL插入方法的性能比较”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“大数据量的情况下MySQL插入方法的性能比较”吧!

插入分析

MySQL中插入一个记录需要的时间由下列因素组成,其中的数字表示大约比例:

连接:(3)

发送查询给服务器:(2)

分析查询:(2)

插入记录:(1x记录大小)

插入索引:(1x索引)

关闭:(1)

如果我们每插入一条都执行一个SQL语句,那么我们需要执行除了连接和关闭之外的所有步骤N次,这样是非常耗时的,优化的方式有一下几种:

在每个insert语句中写入多行,批量插入

将所有查询语句写入事务中

利用Load Data导入数据

每种方式执行的性能如下。

Innodb引擎

InnoDB 给 MySQL 提供了具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。InnoDB 提供了行锁(locking on row level)以及外键约束(FOREIGN KEY constraints)。

InnoDB 的设计目标是处理大容量数据库系统,它的 CPU 利用率是其它基于磁盘的关系数据库引擎所不能比的。在技术上,InnoDB 是一套放在 MySQL 后台的完整数据库系统,InnoDB 在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。

测试环境

Macbook Air 12mid apache2.2.26 php5.5.10 mysql5.6.16

总数100W条数据

插入完后数据库大小38.6MB(无索引),46.8(有索引)

无索引单条插入 总耗时:229s 峰值内存:246KB

有索引单条插入 总耗时:242s 峰值内存:246KB

无索引批量插入 总耗时:10s 峰值内存:8643KB

有索引批量插入 总耗时:16s 峰值内存:8643KB

无索引事务插入 总耗时:78s 峰值内存:246KB

有索引事务插入 总耗时:82s 峰值内存:246KB

无索引Load Data插入 总耗时:12s 峰值内存:246KB

有索引Load Data插入 总耗时:11s 峰值内存:246KB

MyIASM引擎

MyISAM 是MySQL缺省存贮引擎。设计简单,支持全文搜索。

测试环境

Macbook Air 12mid apache2.2.26 php5.5.10 mysql5.6.16

总数100W条数据

插入完后数据库大小19.1MB(无索引),38.6(有索引)

无索引单条插入 总耗时:82s 峰值内存:246KB

有索引单条插入 总耗时:86s 峰值内存:246KB

无索引批量插入 总耗时:3s 峰值内存:8643KB

有索引批量插入 总耗时:7s 峰值内存:8643KB

无索引Load Data插入 总耗时:6s 峰值内存:246KB

有索引Load Data插入 总耗时:8s 峰值内存:246KB

总结

我测试的数据量不是很大,不过可以大概了解这几种插入方式对于速度的影响,最快的必然是Load Data方式。这种方式相对比较麻烦,因为涉及到了写文件,但是可以兼顾内存和速度。

测试代码

<?php$dsn='mysql:host=localhost;dbname=test';$db=newPDO($dsn,'root','',array(PDO::ATTR_PERSISTENT=>true));//删除上次的插入数据$db->query('deletefrom`test`');//开始计时$start_time=time();$sum=1000000;//测试选项$num=1;if($num==1){//单条插入for($i=0;$i<$sum;$i++){$db->query("insertinto`test`(`id`,`name`)values($i,'tsetssdf')");}}elseif($num==2){//批量插入,为了不超过max_allowed_packet,选择每10万插入一次for($i=0;$i<$sum;$i++){if($i==$sum-1){//***一次if($i%100000==0){$values="($i,'testtest')";$db->query("insertinto`test`(`id`,`name`)values$values");}else{$values.=",($i,'testtest')";$db->query("insertinto`test`(`id`,`name`)values$values");}break;}if($i%100000==0){//平常只有在这个情况下才插入if($i==0){$values="($i,'testtest')";}else{$db->query("insertinto`test`(`id`,`name`)values$values");$values="($i,'testtest')";}}else{$values.=",($i,'testtest')";}}}elseif($num==3){//事务插入$db->beginTransaction();for($i=0;$i<$sum;$i++){$db->query("insertinto`test`(`id`,`name`)values($i,'tsetssdf')");}$db->commit();}elseif($num==4){//文件loaddata$filename=dirname(__FILE__).'/test.sql';$fp=fopen($filename,'w');for($i=0;$i<$sum;$i++){fputs($fp,"$i,'testtest'\r\n");}$db->exec("loaddatainfile'$filename'intotabletestfieldsterminatedby','");}$end_time=time();echo"总耗时",($end_time-$start_time),"秒\n";echo"峰值内存",round(memory_get_peak_usage()/1000),"KB\n";?>

感谢各位的阅读,以上就是“大数据量的情况下MySQL插入方法的性能比较”的内容了,经过本文的学习后,相信大家对大数据量的情况下MySQL插入方法的性能比较这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!