大数据量下MySQL插入方法的性能比较
技术百科
黄舟
发布时间:2017-02-23
浏览: 次 不管是日常业务数据处理中,还是数据库的导入导出,都可能遇到需要处理大量数据的插入。插入的方式和数据库引擎都会对插入速度造成影响,这篇文章旨在从理论和实践上对各种方法进行分析和比较,方便以后应用中插入方法的选择。
插入分析
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方式。这种方式相对比较麻烦,因为涉及到了写文件,但是可以兼顾内存和速度。
测试代码
true));
//删除上次的插入数据
$db->query('delete from `test`');
//开始计时
$start_time = time();
$sum = 1000000;
// 测试选项
$num = 1;
if ($num == 1){
// 单条插入
for($i = 0; $i < $sum; $i++){
$db->query("insert into `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("insert into `test` (`id`, `name`) values $values");
} else {
$values .= ",($i, 'testtest')";
$db->query("insert into `test` (`id`, `name`) values $values");
}
break;
}
if ($i%100000 == 0) { //平常只有在这个情况下才插入
if ($i == 0){
$values = "($i, 'testtest')";
} else {
$db->query("insert into `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("insert into `test` (`id`,`name`) values ($i,'tsetssdf')");
}
$db->commit();
} elseif ($num == 4) {
// 文件load data
$filename = dirname(__FILE__).'/test.sql';
$fp = fopen($filename, 'w');
for($i = 0; $i < $sum; $i++){
fputs($fp, "$i,'testtest'\r\n");
}
$db->exec("load data infile '$filename' into table test fields terminated by ','");
}
$end_time = time();
echo "总耗时", ($end_time - $start_time), "秒\n";
echo "峰值内存", round(memory_get_peak_usage()/1000), "KB\n";
?>以上就是MySQL大量数据插入各种方法性能分析与比较,更多相关内容请关注PHP中文网(www.)!
# 放在
# 在这个
# 相关内容
# 数据处理
# 会对
# 几种
# 完后
# mysql
# 中文网
# 单条
# 数据库系统
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Python生成器表达式内存优化_惰性计算说明【指
- 如何高效识别并拦截拼接式恶意域名 spam
- 如何在Golang中使用time处理时间_Gola
- 如何在 Go 中可靠地测试含 time.Time
- 如何在 Go 中正确测试带 Cookie 的 HT
- Win10如何卸载自带Edge_Win10彻底卸载
- Python文件管理规范_工程实践说明【指导】
- Win11怎么关闭应用权限_Windows11相机
- Win11怎么关闭自动调节亮度_Windows11
- 如何在Golang中捕获JSON序列化错误_Gol
- php下载安装后memory_limit怎么设置_
- Win10如何关闭安全中心所有通知 Win10禁用
- Win11笔记本怎么看电池健康度_Win11电池报
- 如何在Golang中配置代码格式化工具_使用gof
- 如何在Golang中编写端到端测试_Golang
- Windows10如何重置此电脑_Windows1
- Win11怎么设置任务栏大小_Windows11注
- Windows10系统怎么查看CPU核心数_Win
- Windows10如何彻底关闭自动更新_Win10
- Windows10如何更改任务栏高度_Win10解
- Win10怎样卸载TeamViewer_Win10
- php怎么下载安装后设置错误日志_phpini l
- Ajax提交表单PHP怎么接收_处理Ajax发送的
- c++获取当前时间戳_c++ time函数使用详解
- 如何在Golang中理解指针比较_Golang地址
- Drupal 中 HTML 链接被双重转义导致渲染
- Windows10如何更改系统字体大小_Win10
- Mac如何与安卓手机传文件_Mac和Android
- 如何在 Go 开发中正确处理本地包导入与远程模块路
- Win11怎么清理C盘系统错误报告_Win11清理
- Linux怎么查找死循环进程_Linux系统负载分
- 如何用::实现单例模式_php静态方法与作用域操作
- 如何使用Golang log记录不同级别日志_Go
- php怎么捕获异常_trycatch结构处理运行时
- 如何使用 Python 合并文件夹内多个 Exce
- 如何使用Golang构建简易投票统计功能_Gola
- PhpStorm怎么调试PHP代码_PhpStor
- Win10怎样清理C盘浏览器缓存_Win10清理浏
- 零基础学会Python自动化办公_高效处理Exce
- Golang如何实现基本的用户注册_Golang用
- Win11怎么设置系统还原_Windows11系统
- Mac的“预览”如何合并多个PDF_Mac文件处理
- 如何在 Django 中修改用户密码后保持会话不丢
- php485支持哪些操作系统_php485跨系统支
- GML (Geography Markup Lan
- Windows怎样关闭桌面弹窗广告_Windows
- Win11怎么连接蓝牙耳机_Win11蓝牙设备配对
- Win11怎么开启游戏模式_Win11优化游戏帧数
- 如何使用Golang开发基础文件下载功能_Gola
- Win11怎么快速锁屏_Win11一键锁屏快捷键W


QQ客服