首先来讲MyISAM:

MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。下图是MyISAM索引的原理图:

这里设表一共有三列,假设我们以Col1为主键,则上图是一个MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件仅仅保存数据记录的地址。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。如果我们在Col2上建立一个辅助索引,则此索引的结构如下图所示:

同样也是一颗B+Tree,data域保存数据记录的地址。因此,MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。

MyISAM的索引方式也叫做“非聚集”的,之所以这么称呼是为了与InnoDB的聚集索引区分。

 
再来讲InnoDB:

虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。

第一个重大区别是InnoDB的数据文件本身就是索引文件。从上文知道,MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。

上图是InnoDB主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。

第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域。例如,下图为定义在Col3上的一个辅助索引:

这里以英文字符的ASCII码作为比较准则。聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。

了解不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助,例如知道了InnoDB的索引实现后,就很容易明白为什么不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。再例如,用非单调的字段作为主键在InnoDB中不是个好主意,因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择。
 
 
 
补充 :
聚集索引和非聚集索引:

聚集索引(InnoDB中的主索引)

  一种索引,该索引中键值的逻辑顺序决定了表中相应行的物理顺序。 
  聚集索引确定表中数据的物理顺序。聚集索引类似于电话簿,后者按姓氏排列数据。由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引。但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样。 
     
     聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。例如,如果应用程序执行 的一个查询经常检索某一日期范围内的记录,则使用聚集索引可以迅速找到包含开始日期的行,然后检索表中所有相邻的行,直到到达结束日期。这样有助于提高此 类查询的性能。同样,如果对从表中检索的数据进行排序时经常要用到某一列,则可以将该表在该列上聚集(物理排序),避免每次查询该列时都进行排序,从而节 省成本。 
    

     当索引值唯一时,使用聚集索引查找特定的行也很有效率。例如,使用唯一雇员 ID 列 emp_id 查找特定雇员的最快速的方法,是在 emp_id 列上创建聚集索引或 PRIMARY KEY 约束。

    聚集索引一般用于选择单调的字段建立。

非聚集索引(MySIAM)

  一种索引,该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同。

MyISAM和InnoDB索引实现区别的更多相关文章

  1. MyISAM 和 InnoDB 索引的区别

      阅读目录 一 MyISAM索引实现 二 InnoDB索引实现 三 InnoDB索引和MyISAM索引的区别 回到顶部 一 MyISAM索引实现 1. 主键索引 MyISAM引擎使用B+树作为索引结 ...

  2. MyISAM与InnoDB两者之间区别与选择

    一.MyISAM与InnoDB两者之间区别 1.MyISAM:默认表类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法 ...

  3. MyISAM和InnoDB索引区别

    MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址.下图是MyISAM索引的原理图: 图8 这里设表一共有三列,假设我们以Col1为主键,则图8是一个MyISAM表 ...

  4. innodb和myisam对比及索引原理区别

    InnoDB和MyISAM是很多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,5.7之后就不一样了 1.事务和外键 InnoDB具有事务,支持4个事务隔离级别,回滚,崩溃修复能力和多版 ...

  5. MyISAM索引和InnoDB索引的区别

    首先你要知道: 无论是Myisam和Innodb引擎,如果在建表的时候没有显示的定义一行主键列的话,他内部都会自动创建一个隐藏的主键索引: 主键索引以外的索引假设称为次索引:首先Myisam和Inno ...

  6. myisam和innodb索引实现的不同

    1.MyISAM 使用B+Tree 作为索引结构,叶子节点的data存放指针,也就是记录的地址.对于主键索引和辅助索引都是一样的.2.InnoDB 也使用B+Tree作为索引结构,也别需要注意的是,对 ...

  7. MyISAM和InnoDB索引实现对比

    MyISAM索引实现 MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址.如图:  这里设表一共有三列,假设我们以Col1为主键,则上图是一个MyISAM表的主索引 ...

  8. MyISAM与InnoDB之间的区别

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

  9. MySQL存储引擎MyISAM和InnoDB有哪些区别?

    一.MyISAM和InnoDB的区别有哪些? 1.InnoDB支持事务,MyISAM不支持.对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在be ...

随机推荐

  1. 初识RESTful

    前言:两个月没写博客了,我真是太贱了哈哈.先简单说下我这两个月做了啥吧.8月26号从BIGO离职,回学校准备秋招.9月初时才发现已经错过秋招内推时间,其实秋招内推拿offer是有较大概率的.9月才开始 ...

  2. 实时滚动图表绘制方法: LightningChart教程 + 源码下载

    LightningChart图形控件彻底发挥了GPU加速和性能优化的最大效应,能够实时呈现超过10亿数据点的庞大数据,为大家提供先进与快速的图表库.这里的实时图实现的比较简单,大家先试一下这个效果,熟 ...

  3. 二维码开源库ZBar-吐槽篇

    前不久在网上看到一篇文章<QR-Decoder-OV5640 二维码识别> ,是某开发板的教程.记得对应的开发板以前购买过,当初只是为了看OV5640的JPG的输出效果,结果由于公司奇葩的 ...

  4. 关于 IO的同步异步间要描述

    IO在计算机中指Input/Output,也就是输入和输出.由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘.网络等,就需要IO接口. 比如你打开 ...

  5. Scrapy-简单介绍

    Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. 其最初是为了 页面抓取 (更确切来说, 网络抓取 )所设计的, ...

  6. Java经典编程题50道之六

    输入两个正整数m和n,求其最大公约数和最小公倍数. public class Example06 {    public static void main(String[] args) {       ...

  7. 修改maven项目jdk版本,并解决Dynamic Web Module 3.1 requires Java 1.7 or newer错误

    使用maven的时候,默认会使用1.5版本的JDK,并且创建项目时也会是1.5版本. 但是我想用JDK1.7版本,所以我手动将maven项目JDK改为1.7版本. 手动修改JDK版本为1.7以后,项目 ...

  8. angular aot编译报错 ERROR in ./src/main.ts 解决方法

    昨天打包项目时遇到下图这样的错误: 开始以为了某些模块存在但未使用,折腾一番无果,后来升级angular-cli就搞定了,方法很简单: 1.删掉node_modules 2.更改package.jso ...

  9. JS Cookie丢失问题

    JS Cookie丢失问题 前些天有人问我vue中使用proxy发送请求,为什么请求时cookie丢失,首先说一下我对cookie的理解: 1.cookie在正常情况下是会在每次请求时自动携带, 2. ...

  10. CodeForces - 730A 贪心+模拟

    贪心策略: 1.只有一个最大值,选着第二大的一起参加比赛减分. 2.有奇数个最大值,选择三个进行比赛. 3.偶数个最大值,选择两个进行比赛. 为什么不把最大值全部选择? 因为最多只能选五个,有可能选择 ...