MySQL存储引擎差异化实验
本篇把MySQL最常用的存储引擎给大家做一个介绍,然后通过插入、修改和并发实验来了解和验证一下它们之间的一些差异。
一、MySQL存储引擎简介
存储引擎在MySQL结构里占据核心的位置,是上层抽象接口和存储的物理文件之间的桥梁。每一种storage engine 架构组件都是根据特定的场合来设计的,负责数据的 I/O 操作,并启用一些特性的支持。

MySQL存储引擎被设计为插件式结构,每种存储引擎可从运行的mysql里动态加载或卸载。我们可以在客户端连接后用show plugins;查看当前加载的插件,用install plugin xxx;或者 uninstall plugin xxx;来安装或卸载。
查看服务器当前支持的引擎命令:
mysql> show engines;
主要的几种引擎介绍如下:
InnoDB:支持事务操作,支持行级锁,支持外键。独立表结构的花每个表单文件存储,是MySQL5.5之后的默认引擎。
MyISAM:使用广泛,数据量不是特别大时性能很高,是5.5之前的默认引擎。
Memory:数据直接放在内存,极快的访问速度,但是空间很受限。
MRG_MYISAM:可以把MyISAM表分组管理。
Federated:可以把不同物理服务器连接成一个逻辑服务器,适合分布式管理。
CSV:导入导出成CSV格式,便于和其他软件数据交换。
我们可以配置php.ini文件或者在server启动时,可以通过--default-storage-engine参数来指定默认的存储引擎。也可以在mysql运行状态下动态改变默认引擎:
show variables like 'default_storage_engine';
SET default_storage_engine=MYISAM;
数据库的每个表可以使用不同的引擎:
create table t_a(uid int,uname varchar(50)) engine=innodb;
也可以动态修改表的引擎:
alter table t_a engine=MyISAM;
二、MySQL存储引擎的文件组成与备份
MySQL主要的动态文件有日志文件、配置文件和存储引擎的数据文件
1、日志文件
种类非常多,我们也可以在这些变量里找到innodb的特殊日志文件:
show variables like '%log%';
2、配置和连接文件
my.cnf是数据库的主要配置文件,如果我们做了主从配置,则还有master.info等配置信息文件。
linux下支持tcp和socket连接,可以通过配置my.cnf或者连接时增加参数来确定mysql --protocol=tcp,如果是socket方式则一般会通过socket文件来连接/tmp/mysql.sock。
3、数据文件
每一种存储引擎都有.frm 表元数据文件。然后每种引擎都有自己的一些特有特有格式的文件:
.myd (MyData)是MyISAM数据文件,.myi (MyIndex)是MyISAM索引文件(b-tree、full-text等)。
innodb的共享表空间存在ibdata文件里,如果配置成独享表空间的话(mysql默认)每个表还会有对应.ibb文件。我们可以通过变量查询和设置这些配置:
show variables like ‘%innodb%’; 其中innodb_file_per_table设置是否是独享表空间,innodb_data_file_path 和innodb_data_home_dir用来指定表的存放位置。
备份:
1、逻辑备份
逻辑备份是不停机的情况下比较好的备份方式,通过mysqldump或者其他方式来导出sql语句。
2、物理备份
物理备份在某些情况是更加直接和快速的方式。myisam引擎因为是非事务没有独立日志,一般备份3个文件即可,也可以通过mysqlhotcopy来进行物理备份。
innodb 因为事物需要有日志文件,如果在运行状态则不能手工来备份,需要一些商业化的工具比如ibbackup来支持物理备份。
3、主从物理备份
因为物理备份一般需要锁库,在线上数据库上我们如果设置了主从服务器并且有多台从库的话,可以暂停一台从库,然后实行物理备份。
三、插入和更新数据
我们先创建3个引擎的数据表user_myisam、user_innodb、user_memory,表的结构是一样的:
create table user_myisam (
uid int auto_increment,
uname varchar(50) not null default '',
type tinyint not null default 0,
ctime timestamp not null default current_timestamp,
primary key (uid)
) engine=myisam, charset=utf8;
我们在生成数据时,可以使用一条条数据插入、导入sql文件、或者批量插入的方式进行。
导入sql文件是有大小限制的,我们可以通过max_allowed_packet变量来查看,一般默认为1M,所以导入大量数据时需要增大这个变量:
show variables like 'max_allowed_packet';
显然,数据量很大时,批量插入的方式是效率最高的:
insert into tbl values(),(),()...
经过对比,虽然memory引擎插入和查询修改的速度都极快,单只支持几万行数据,即使调大了内存参数也只能支持10多万行。所以memory一般用在一些数据量比较小的特殊场合,比如在线用户表、或者缓存一些配置信息等。
我们用批量插入的方式把myisam和innodb的表各插入了1千万行数据(每次插入1万行或更多),myisam的速度要稍快些,没有调优的情况下几分钟时间就可以了。
更新和查询的数据对比:
在一个进程操作的情况下,myisam的更新和查询速度都会稍快于innodb。
特别注意的一点是,innodb查询表的行数需要全表扫描,速度会非常慢,查询1千万行数据的表最多时要6、7s,所以在项目里一定要控制innodb表的总数查询,一定要缓存。而myisam因为保存了总行数是极快的。


四、innodb的事务支持和锁
innodb的事物支持4种隔离级别:
read uncommitted:脏读,在自己的事务里能看到别的事务修改但未提交的数据。
read committed:不可重复读,虽然别的事务未提交的数据看不到,但是提交后就可以了,所以不能多次读取,数据可能不一致。
repeatable read:可重复读,事务做了隔离,但还是可以并发的。
serializable:串行,最严格的方式,事务单行处理,不会并行。
查看当前和全局的事务隔离级别:
SELECT @@GLOBAL.tx_isolation, @@tx_isolation;
可以通过以下命令来改变设置:
set global transaction isolation level read uncommitted;
我们可以通过2个session然后设置set autocommit=0来进行测试和验证这4种事务隔离级别的差别,在自己的项目里也可以根据情况来改变。越高的隔离级别对性能影响越大,innodb默认是repeatable read方式。
mysql有3种锁:
1、表级锁:myisam的默认形式,开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。可以查看表锁的一些情况:
show status like 'table%';
2、行级锁:innodb的默认形式,开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
需要注意的是,innodb只有在能利用索引的操作时才执行行级锁,如果查询或更新操作不能利用索引还是会使用表级锁的。查看行锁状态:
show
status like 'innodb_row_lock%';
3、页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
五、并发测试与参数调优总结
虽然在上面单进程的情况下,myisam在插入查询和更新等操作中性能都比较高,但是在我们模拟高并发的情况下,可以看出innodb的销量明显占优了。
我们用apache的ab工具来测试3000次30个并发的请求,每个请求在1千万数据里随机找5行数据进行修改和查询(用到索引),测试结果如下:
myisam的测试数据:

innodb的测试结果:

myisam的一些参数优化:
read_buffer_size缓存大小
设置concurrent_insert为2,在尾部插入数据,不影响select
打开delay_key_write
innodb的一些参数:
设置事务提交后数据保存方式:
innodb_flush_log_at_trx_commit
0 每秒保存 1 每事务保存 2 系统决定
innodb_buffer_pool缓存大小:
show status like 'innodb_buffer_pool%';
可以用show engine innodb status\G查看innodb的一些情况:
innodb_read_io_threads读写进程数
innodb_write_io_threads
innodb_io_capacity合并写入数量
innodb_io_capacity=5000;
set global innodb_stats_on_metadata=0;关闭元数据更新
经过我们的一些操作对比,可以看出:
Memory虽然是高效的引擎,但是由于是临时数据而且有数据量的限制,适合与性能要求高数据量小的地方,和缓存的效果类似。
MyISAM适合数据量不是特别大并发不太高的大部分场合,性能都占优,并且也支持全文检索。如果不需要事务支持的话MyISAM绝对是最优的方式。
而InnoDB 则更适合与大并发大数据量的场合,除了支持事务,在高并发时行级锁的优势就会发挥出来。当然我们需要在代码和设计里去规避innodb本身的一些的问题,例如尽可能使用到索引,缓存表的行数等。
MySQL存储引擎差异化实验的更多相关文章
- Mysql存储引擎及选择方法
0x00 Mysql数据库常用存储引擎 Mysql数据库是一款开源的数据库,支持多种存储引擎的选择,比如目前最常用的存储引擎有:MyISAM,InnoDB,Memory等. MyISAM存储引擎 My ...
- Mysql存储引擎之TokuDB以及它的数据结构Fractal tree(分形树)
在目前的Mysql数据库中,使用最广泛的是innodb存储引擎.innodb确实是个很不错的存储引擎,就连高性能Mysql里都说了,如果不是有什么很特别的要求,innodb就是最好的选择.当然,这偏文 ...
- MySQL存储引擎总结
MySQL存储引擎总结 作者:果冻想 字体:[增加 减小] 类型:转载 这篇文章主要介绍了MySQL存储引擎总结,本文讲解了什么是存储引擎.MyISAM.InnoDB.MEMORY.MERGE等内 ...
- 数据库 --> MySQL存储引擎介绍
MySQL存储引擎介绍 MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Access Method:有索引的顺序访问方法)所改良.虽然 ...
- 7.Mysql存储引擎
7.表类型(存储引擎)的选择7.1 Mysql存储引擎概述 mysql支持插件式存储引擎,即存储引擎以插件形式存在于mysql库中. mysql支持的存储引擎包括:MyISAM.InnoDB.BDB. ...
- MYSQL存储引擎介绍--应用场景
MySQL存储引擎通常有哪3种?各自分别有什么特点?应用场景是哪些? MySQL5.5以后默认使用InnoDB存储引擎,其中InnoDB和BDB提供事务安全表,其它存储引擎都是非事务安全表.若要修改默 ...
- Mysql存储引擎的选择
Mysql存储引擎概述 mysql的存储引擎是插件式的,用户可以根据需求选择如何存储和索引数据是否使用事务等. Mysql支持多种存储引擎,用户可以选择不同的引擎来提高应用的效率,灵活的存储方案,存储 ...
- 【mysql存储引擎】
看你的mysql现在已提供什么存储引擎: mysql> show engines; 看你的mysql当前默认的存储引擎: mysql> show variables like '%st ...
- mysql 存储引擎学习
现在我们常用的MySQL存储引擎主要是两种:InnoDB and MyISAM. 1.MyISAM 执行效率高 不支持事务 不支持外键 每个MyISAM在磁盘上存储成3个文件,其中文件名和表名都相同, ...
随机推荐
- Android ListView分页载入(服务端+android端)Demo
Android ListView分页载入功能 在实际开发中经经常使用到,是每一个开发人员必须掌握的内容,本Demo给出了服务端+Android端的两者的代码,并成功通过了測试. 服务端使用MyEcli ...
- SPPS java 创template
最近写信给学校一个部门java plug for spss. 当加到变量超过70个月,然后保存,SPSS它会在错误的地方报. 解决方案: 每添加70提交变量. 版权声明:本文博主原创文章.博客,未经同 ...
- 浅析MVC和说媒的过程
什么是MVC? MVC 全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面 显 ...
- Chapter 2 User Authentication, Authorization, and Security(4):限制SA帐户管理权限
原版的:http://blog.csdn.net/dba_huangzj/article/details/38817915,专题文件夹:http://blog.csdn.net/dba_huangzj ...
- url参数中出现+、空格、=、%、&、#等字符的解决办法
url出现了有+,空格,/,?,%,#,&,=等特殊符号的时候,可能在服务器端无法获得正确的参数值,如何是好?解决办法将这些字符转化成服务器可以识别的字符,对应关系如下:URL字符转义 用其它 ...
- java main方法背后的故事?(转)
jvm java 看似一种语言,实则一个巨大的体系的王国,开发这么多年了,还是没有搞懂,我以为我懂了,可是过了一段时间又忘了,所以说还是没懂 1.main方法说起 编译完我们的java文件后,需要有个 ...
- Following unknown configure options were used:--enable-fpm
跑cd php-5.2.13安装时间 ./configure --prefix=/usr/local/php/ --with-config-file-path=/usr/local/php/etc ...
- 设计模式之前奏(UML类图)
原文:设计模式之前奏(UML类图) 本人菜菜一个,最近一直在博客园游走闲逛,看到了各种技术,各种各种…….便看到了大话设计模式这本书,下了电子版的看了看第一章,感觉相当不错,不仅通俗易懂,而且与实际案 ...
- JAVA学习(二):JDK介绍及其结构、用途
JDK介绍及其结构.用途 1.JDK的介绍 JDK是Java Development Kit 的缩写.是Sun Microsystems针对Java开发员的产品.它由一个处于操作系统层之上的执行环境还 ...
- [Python学习] 模块三.基本字符串
于Python最重要的数据类型包含字符串.名单.元组和字典.本文重点介绍Python基础知识. 一.字符串基础 字符串指一有序的字符序列集合,用单引號.双引號.三重(单 ...