本篇把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. TestNg显示器(一个)-----监听器,类型和配置使用---另外META-INF详细解释

    原创文章,版权所有所有.转载,归因:http://blog.csdn.net/wanghantong/article/details/40404939 TestNg提供了听众和拦截多种接口开发我们自己 ...

  2. NYOJ 372 巧克力的

    巧克力 时间限制:4000 ms  |  内存限制:65535 KB 难度:2 描写叙述 布欧能够把人变成巧克力吃了来添加他的能量,也有可能降低. 如今布欧变了n*m个巧克力,并把巧克力排成一个n*m ...

  3. 摆弄【Nhibernate 协会制图--导乐陪伴分娩】

    现有两个实体,Dog和 Master,映射到数据库表中如上图所看到的.一个Dog仅仅同意相应一个Master,但一个Master能够有多个Dog.我们在查询Dog的时候.往往还须要知道其主人Maste ...

  4. w3wp占用CPU过高

    w3wp占用CPU过高 在此之前项目有发生过两次类似的状况,都得以解决,但最近又会发现偶尔CPU会跑满,虽然之前使用过WinDbg解决过两次问题但人的记忆是不可靠的,今天处理同样问题的时候还是遇到了一 ...

  5. HDU 2289 Cup(可以二分法,但是除了它的一半?)

    这道题目.运营商做数学题?算上两个子主题做?顶多算一个水主要议题... 首先,没有实际的二分法,但是,我们发现了一个新的解决方案,以取代二分法. 若果按照i从0,每次添加0.00000001我一直枚举 ...

  6. Jg-Table 过程1 (jgTable)

    近期使用Table,他写了一.时间紧急.还有一点简单的无精写作.但主要的功能已经支持, 大家有时间可以看看,欢迎吐槽 jg-table 1.0                 1. 支持固定头角    ...

  7. linux命令之删除

      linux删除文件夹非常easy,非常多人还是习惯用rmdir,只是一旦文件夹非空,就陷入深深的苦恼之中,如今使用rm -rf命令就可以. 直接rm就能够了,只是要加两个參数-rf 即:rm -r ...

  8. mapxtreme演示V1.3

    mapxtreme演示V1.3   mapxtreme地图相关基本功能的演示其中包括 鹰眼地图,图层控制,发达,缩小,平移地图,地图模糊查询,中点工具,距离测量工具,面积测量工具,图元信息查看工具,各 ...

  9. vim cheat sheet

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzE1Mjg5NQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  10. NSIS:强制结束软件进程

    原文NSIS:强制结束软件进程 有时候,我们选择卸载软件后发现安装目录中的主文件依然存在,不是我们卸载代码写的不对,而是卸载的时候软件根本就没有关闭! 在卸载前加上下面这个宏可以在一定程度上免除上述的 ...