本篇把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存储引擎差异化实验的更多相关文章

  1. Mysql存储引擎及选择方法

    0x00 Mysql数据库常用存储引擎 Mysql数据库是一款开源的数据库,支持多种存储引擎的选择,比如目前最常用的存储引擎有:MyISAM,InnoDB,Memory等. MyISAM存储引擎 My ...

  2. Mysql存储引擎之TokuDB以及它的数据结构Fractal tree(分形树)

    在目前的Mysql数据库中,使用最广泛的是innodb存储引擎.innodb确实是个很不错的存储引擎,就连高性能Mysql里都说了,如果不是有什么很特别的要求,innodb就是最好的选择.当然,这偏文 ...

  3. MySQL存储引擎总结

    MySQL存储引擎总结 作者:果冻想 字体:[增加 减小] 类型:转载   这篇文章主要介绍了MySQL存储引擎总结,本文讲解了什么是存储引擎.MyISAM.InnoDB.MEMORY.MERGE等内 ...

  4. 数据库 --> MySQL存储引擎介绍

    MySQL存储引擎介绍 MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Access Method:有索引的顺序访问方法)所改良.虽然 ...

  5. 7.Mysql存储引擎

    7.表类型(存储引擎)的选择7.1 Mysql存储引擎概述 mysql支持插件式存储引擎,即存储引擎以插件形式存在于mysql库中. mysql支持的存储引擎包括:MyISAM.InnoDB.BDB. ...

  6. MYSQL存储引擎介绍--应用场景

    MySQL存储引擎通常有哪3种?各自分别有什么特点?应用场景是哪些? MySQL5.5以后默认使用InnoDB存储引擎,其中InnoDB和BDB提供事务安全表,其它存储引擎都是非事务安全表.若要修改默 ...

  7. Mysql存储引擎的选择

    Mysql存储引擎概述 mysql的存储引擎是插件式的,用户可以根据需求选择如何存储和索引数据是否使用事务等. Mysql支持多种存储引擎,用户可以选择不同的引擎来提高应用的效率,灵活的存储方案,存储 ...

  8. 【mysql存储引擎】

    看你的mysql现在已提供什么存储引擎: mysql> show engines;   看你的mysql当前默认的存储引擎: mysql> show variables like '%st ...

  9. mysql 存储引擎学习

    现在我们常用的MySQL存储引擎主要是两种:InnoDB and MyISAM. 1.MyISAM 执行效率高 不支持事务 不支持外键 每个MyISAM在磁盘上存储成3个文件,其中文件名和表名都相同, ...

随机推荐

  1. flask+gevent+gunicorn+nginx 初试

    1.安装flask pip install flask 2.安装gevent pip install gevent 3.安装gunicorn pip install gunicorn 版本信息例如以下 ...

  2. 第七个问题(枚举和set)

    set添加元素是基于equals和hashCode函数来确定的两个要素是否是同一物体. public final boolean equals(Object other) 当指定对象等于此枚举常量时, ...

  3. OpenNMS在安装”我找不到jrrd.dll“错误的解决方法

    在Windows 2003 Server(虚拟机)安装OpenNMS.找不到jrrd.dll错误.尝试从学习OpenNMS官网下载jrrd-1.0.7.tar.gz,我们没有发现标dll文件,编译需要 ...

  4. 移动端 Retina屏 各大主流网站1px的解决方案

    Retina屏的移动设备如何实现真正1px的线? 在retina屏下面,如果你写了这样的meta <meta name="viewport" content="in ...

  5. Atitit..文件上传组件选择and最佳实践的总结(2)----HTTP

    Atitit..文件上传组件选型and最佳实践总结(2)----断点续传 1. 断点续传的原理 1 2. 怎样推断一个插件/控件是否支持断点续传?? 1 3. 经常使用的组件选型结果::马 1 4.  ...

  6. 推荐他们认为有用Sublime Text3小工具

    所有插件package control安装.一些国家的破解版sublime该插件是建立,安装自己的百度没有内置的方法,这里就不再重复 打开sublime.ctrl+shift+P,输入pis回车,稍等 ...

  7. (大数据工程师学习路径)第一步 Linux 基础入门----用户及文件权限管理

    用户及文件权限管理 实验介绍 1.Linux 中创建.删除用户,及用户组等操作. 2.Linux 中的文件权限设置. 一.Linux 用户管理 Linux 是一个可以实现多用户登陆的操作系统,比如“李 ...

  8. Unity模拟龙之谷人物行走简单控制

    我个人挺喜欢龙之谷(DN)的人物控制的(不是广告哈....),就是人物太萌了一点,动作.打击感都挺好的. 今天用Unity简单模仿了一下DN的人物控制,当然,游戏里面动作非常多,我这里仅仅做了简单的w ...

  9. 【Hibernate步步为营】--复合主键映射具体解释

    上篇文章讨论了继承映射,它是对象模型中最主要的特性,对于继承映射它的主要区分是字段类型的不同,所以在生成表结构时须要有新列来标识数据的类型,能够使用<subclass>标签并在标签中加入d ...

  10. windows server 2008见安装IIS方法(解决)

    windows server 2008见安装IIS方法(解决) 刚开始有点蒙,后来才知道原来如此.! . 右键点击[我的电脑]--[管理]--[字符]--[加入角色]--仅落后win7像.啊! 版权声 ...