大家都知道在MySQL中,MyISAM比InnoDB查询快,但很多人都不知道其中的原理。

今天我们就来聊聊其中的原理,另外也验证下是否MyISAM比InnoDB真的查询快。

在探索其中原理之前,我们先验证下查询速度。

验证

下面我们一起来验证两个问题:

1、通过主键查询,MyISAM是否比InnoDB查询快?

2、通过非主键字段查询,MyISAM是否比InnoDB查询快?

验证前准备

订单表结构:

CREATE TABLE `trade` (
`id` INT(11) NULL DEFAULT NULL,
`trade_no` INT(11) NULL DEFAULT NULL,
UNIQUE INDEX `id` (`id`),
INDEX `trade_no` (`trade_no`)
)
COMMENT='订单'
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;

分别创建不同引擎的表trade_myisam、trade_innodb,并插入10万条测试数据,如下:

这里我们字段都采用Int类型,是为了方便我们,使用区间查询,来验证查询速度。

验证思路

1、分别通过id、trade_no查询10000~20000区间的记录,并获得查询所花费时间。

2、循环查询100次,并取得查询耗费时间平均值。

3、通过对比查询
耗费
时间平均值,来判断性能。

下面我们一起来验证下,文章开头的两个问题:

1、主键查询

C#实现主键查询Id在10000~20000区间,查询耗费时间平均值代码如下:

using (var conn = new MySqlConnection(connsql))
{
conn.Open();
//查询次数
var queryTime = 1000;
​
//InnoDB数据引擎:
主键查询
//开始时间
var startTime = DateTime.Now;
for (var i = 0; i < queryTime; i++)
{
//插入
var sql = "select * from trade_innodb where id>=10000 and id<20000";
var sqlComm = new MySqlCommand();
sqlComm.Connection = conn;
sqlComm.CommandText = sql;
sqlComm.ExecuteScalar();
sqlComm.Dispose();
}
//完成时间
var endTime = DateTime.Now;
//耗时
var spanTime = (endTime - startTime) * 1.0 / queryTime;
Console.WriteLine("InnoDB主键查询1000次平均耗时:
" + spanTime.Minutes + "分" + spanTime.Seconds + "秒" + spanTime.Milliseconds + "毫秒");
​
//MyISAM数据引擎:
主键查询
//开始时间
startTime = DateTime.Now;
for (var i = 0; i < queryTime; i++)
{
//插入
var sql = "select * from trade_myisam where id>=10000 and id<20000";
var sqlComm = new MySqlCommand();
sqlComm.Connection = conn;
sqlComm.CommandText = sql;
sqlComm.ExecuteScalar();
sqlComm.Dispose();
}
//完成时间
endTime = DateTime.Now;
//耗时
spanTime = (endTime - startTime) * 1.0 / queryTime;
Console.WriteLine("MyISAM主键查询1000次平均耗时:
" + spanTime.Minutes + "分" + spanTime.Seconds + "秒" + spanTime.Milliseconds + "毫秒");
​
conn.Close();
}

运行结果:

通过上面的图片,可以看到结果: MyISAM查询性能确实比较Innodb快。

2、非主键查询

C#实现费主键查询trade_no在10000~20000区间,查询耗费时间平均值代码如下:

using (var conn = new MySqlConnection(connsql))
{
conn.Open();
//查询次数
var queryTime = 1000;
​
//InnoDB数据引擎:
非主键查询
//开始时间
var startTime = DateTime.Now;
for (var i = 0; i < queryTime; i++)
{
//插入
var sql = "select * from trade_innodb where trade_no>=10000 and trade_no<20000";
var sqlComm = new MySqlCommand();
sqlComm.Connection = conn;
sqlComm.CommandText = sql;
sqlComm.ExecuteScalar();
sqlComm.Dispose();
}
//完成时间
var endTime = DateTime.Now;
//耗时
var spanTime = (endTime - startTime) * 1.0 / queryTime;
Console.WriteLine("InnoDB非主键查询1000次平均耗时:
" + spanTime.Minutes + "分" + spanTime.Seconds + "秒" + spanTime.Milliseconds + "毫秒");
​
//MyISAM数据引擎:
非主键查询
//开始时间
startTime = DateTime.Now;
for (var i = 0; i < queryTime; i++)
{
//插入
var sql = "select * from trade_myisam where trade_no>=10000 and trade_no<20000";
var sqlComm = new MySqlCommand();
sqlComm.Connection = conn;
sqlComm.CommandText = sql;
sqlComm.ExecuteScalar();
sqlComm.Dispose();
}
//完成时间
endTime = DateTime.Now;
//耗时
spanTime = (endTime - startTime) * 1.0 / queryTime;
Console.WriteLine("MyISAM非主键查询1000次平均耗时:
" + spanTime.Minutes + "分" + spanTime.Seconds + "秒" + spanTime.Milliseconds + "毫秒");
​
conn.Close();
}

运行结果:

通过上面的图片,可以看到结果: MyISAM查询性能确实比较Innodb快。

对比结果

通过我们的验证来看,不管是主键还是非主键查询,MyISAM查询性能确实比较Innodb快。
查询速度不一样,肯定是MyISAM与InnoDB有什么区别,下面我们一起来看看它们的区别。

MyISAM与InnoDB区别

通过上面表格对比, InnoDB在做SELECT的时候,要维护的东西比MYISAM引擎多很多,影响查询速度有:

1)数据块,InnoDB要缓存,MyISAM只缓存索引块,  这中间还有换进换出的减少;

2)InnoDB寻址要映射到块,再到行,MyISAM记录的直接是文件的OFFSET,定位比InnoDB要快

3)InnoDB还需要维护MVCC一致;
虽然你的场景没有,但他还是需要去检查和维护

MVCC (Multi-Version Concurrency Control)多版本并发控制 。

索引区别:

MyISAM与InnoDB索引存储方式是不一样的(关于索引请查看《细说MySql索引原理》)。

InnoDB 的表是根据主键进行展开的 B+tree 的聚集索引。
MyISAM则非聚集型索引,MyISAM存储会有两个文件,一个是索引文件,另外一个是数据文件,其中索引文件中的索引指向数据文件中的表数据。

聚集型索引并不是一种单独的索引类型,而是一种存储方式,InnoDB 聚集型索引实际上是在同一结构中保存了 B+tree 索引和数据行。
当有聚簇索引时,它的索引实际放在叶子页中。

下面我们通过2张图,我们就能直观看到这两个引擎,索引结构的区别:

维护MVCC

InnoDB引擎还有需要实现MVCC,这里面也是损耗一定的性能的。

Innodb是通过每一行记录有2个额外的隐藏值来实现,这两个值一个记录这行数据何时被创建,另外一个记录这行数据何时过期(或者被删除)。

但是InnoDB并不存储这些事件发生时的实际时间,相反它只存储这些事件发生时的系统版本号。
这是一个随着事务的创建而不断增长的数字。
每个事务在事务开始时会记录它自己的系统版本号。
每个查询必须去检查每行数据的版本号与事务的版本号是否相同。

最后

通过我们的验证来看,不管是主键还是非主键查询,MyISAM查询性能确实比较Innodb快。
但是MyISAM不支持事务,在实现业务方面有很多麻烦的事情。

关于我们开发中,选择哪个数据引擎的问题。

平常在我们业务系统中,InnoDB数据引擎完全可以满足我们的需求,这两个引擎查询性能差别还是比较小的,完全没必要为了这点性能,给我们带来更多的工作量。
MyISAM引擎更多是用于存储数据仓库,只有查询少量插入的业务场景中,比如系统日志。

欢迎关注公众号【编程乐趣】,了解更多MySQL知识。

MySQL中MyISAM为什么比InnoDB查询快的更多相关文章

  1. MySQL中MyISAM引擎与InnoDB引擎性能简单测试

    [硬件配置]CPU : AMD2500+ (1.8G)内存: 1G/现代硬盘: 80G/IDE[软件配置]OS : Windows XP SP2SE : PHP5.2.1DB : MySQL5.0.3 ...

  2. MySQL中MyISAM引擎及InnoDB引擎的缓存优化设计

    MyISAM引擎中,为了提高io效率以及读取效率,将对磁盘频繁读取的索引数据加载至内存中操作. MyISAM设计了一个在存放在内存中的索引缓冲池Key Cache.Key Cache只缓存索引数据,通 ...

  3. Mysql中MyISAM引擎和InnoDB引擎的比较

    结论 如果不清楚自己应该用什么引擎,那么请选择InnoDB,Mysql5.5+的版本默认引擎都是InnoDB,早期的Mysql版本默认的引擎是MyISAM MyISAM 和 InnoDB的适用场景 M ...

  4. MySQL中MyISAM和InnoDB两种主流存储引擎的特点

    一.数据库引擎(Engines)的概念 MySQ5.6L的架构图: MySQL的存储引擎全称为(Pluggable Storage Engines)插件式存储引擎.MySQL的所有逻辑概念,包括SQL ...

  5. MySQL中MyISAM和InnoDB的区别

    MyISAM和InnoDB的区别 MySQL默认采用的是MyISAM. MyISAM不支持事务,而InnoDB支持.InnoDB的AUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事 ...

  6. 【mysql中myisam和innodb的区别】

    单击进入源网页 要点摘要: 1.查看mysql存储引擎的状态mysql> show engines; 2.查看mysql默认的存储引擎mysql> show variables like ...

  7. MYSQL 中 MyISAM与InnoDB两者之间区别与选择,详细总结,性能对比

    1.MyISAM:默认表类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法.不 ...

  8. MySQL中MyISAM与InnoDB的主要区别对比

    特征 MyISAM InnoDB 聚集索引 否 是 压缩数据 是(仅当使用压缩行格式时才支持压缩MyISAM表.使用压缩行格式和MyISAM的表是只读的.) 是 数据缓存 否 是 加密数据 是(通过加 ...

  9. mysql 中 myisam innodb 的区别

    区别: 1. InnoDB支持事务,MyISAM不支持,对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事 ...

随机推荐

  1. frp实现内网穿透

    frp实现内网穿透 目标 通过外网访问内网设备,本文中实现通过手机的移动流量,可以访问到树莓派设备 设备准备 需要被访问的设备(本文中使用Raspberry Pi`).公网IP设备(本文中使用阿里云 ...

  2. LevelDB 源码解析之 Varint 编码

    GitHub: https://github.com/storagezhang Emai: debugzhang@163.com 华为云社区: https://bbs.huaweicloud.com/ ...

  3. 未来直播 “神器”,像素级视频分割是如何实现的 | CVPR 冠军技术解读

    被誉为计算机视觉领域 "奥斯卡" 的 CVPR 刚刚落下帷幕,2021 年首届 "新内容 新交互" 全球视频云创新挑战赛正火热进行中,这两场大赛都不约而同地将关 ...

  4. java例题_43 求0—7所能组成的奇数个数

    1 /*43 [程序 43 求奇数个数] 2 题目:求 0-7 所能组成的奇数个数. 3 */ 4 5 /*分析 6 * 1.0不能作最高位且最低位只能是1,3,5,7; 7 * 2.没有限定是几位数 ...

  5. vite 动态 import 引入打包报错解决方案

    关注公众号: 微信搜索 前端工具人 ; 收货更多的干货 原文链接: 自己掘金文章 https://juejin.cn/post/6951557699079569422/ 关注公众号: 微信搜索 前端工 ...

  6. Day14_85_通过反射机制修改Class的属性值(IO+Properties)动态修改

    通过反射机制修改Class的属性值(IO+Properties)动态修改 import java.io.FileInputStream; import java.io.FileNotFoundExce ...

  7. Python容器相关操作

    (集合与字典除外)的容器相关操作 (1)容器的拼接 >>> 'abc' + 'def' 'abcdef' (2)容器的重复 >>> (1, 2) * 3 (1, 2 ...

  8. Weekly Contest 137

    1046. Last Stone Weight We have a collection of rocks, each rock has a positive integer weight. Each ...

  9. Python爬取笔趣阁小说,有趣又实用

    上班想摸鱼?为了摸鱼方便,今天自己写了个爬取笔阁小说的程序.好吧,其实就是找个目的学习python,分享一下. 1. 首先导入相关的模块 import os import requests from ...

  10. js去重的两种方法

    去重 去重方法和思路也很多,这里就介绍两种吧. 方法一: 1 2 3 4 5 6 7 8 9 10 11 function unique1(arr) {       var res = [],     ...