在 MySQL 中,主要有四种类型的索引,分别为: B-Tree 索引, Hash 索引, Fulltext 索引和 R-Tree 索引。我们主要分析B-Tree 索引。

B-Tree 索引是 MySQL 数据库中使用最为频繁的索引类型,除了 Archive 存储引擎之外的其他所有的存储引擎都支持 B-Tree 索引。Archive 引擎直到 MySQL 5.1 才支持索引,而且只支持索引单个 AUTO_INCREMENT 列。

不仅仅在 MySQL 中是如此,实际上在其他的很多数据库管理系统中B-Tree 索引也同样是作为最主要的索引类型,这主要是因为 B-Tree 索引的存储结构在数据库的数据检索中有非常优异的表现。

一般来说, MySQL 中的 B-Tree 索引的物理文件大多都是以 Balance Tree 的结构来存储的,也就是所有实际需要的数据都存放于 Tree 的 Leaf Node(叶子节点) ,而且到任何一个 Leaf Node 的最短路径的长度都是完全相同的,所以我们大家都称之为 B-Tree 索引。当然,可能各种数据库(或 MySQL 的各种存储引擎)在存放自己的 B-Tree 索引的时候会对存储结构稍作改造。如 Innodb 存储引擎的 B-Tree 索引实际使用的存储结构实际上是 B+Tree,也就是在 B-Tree 数据结构的基础上做了很小的改造,在每一个Leaf Node 上面出了存放索引键的相关信息之外,还存储了指向与该 Leaf Node 相邻的后一个 LeafNode 的指针信息(增加了顺序访问指针),这主要是为了加快检索多个相邻 Leaf Node 的效率考虑

下面主要讨论MyISAM和InnoDB两个存储引擎的索引实现方式:

1. MyISAM索引实现:MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。

1)主键索引:

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

(图myisam1)

这里设表一共有三列,假设我们以Col1为主键,图myisam1是一个MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件仅仅保存数据记录的地址。

2)辅助索引(Secondary key)

在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。如果我们在Col2上建立一个辅助索引,则此索引的结构如下图所示:

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

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

2. InnoDB索引实现

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

1)主键索引:

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

(图inndb主键索引)

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

2). InnoDB的辅助索引

InnoDB的所有辅助索引都引用主键作为data域。例如,下图为定义在Col3上的一个辅助索引:

        InnoDB 表是基于聚簇索引建立的。因此InnoDB 的索引能提供一种非常快速的主键查找性能。不过,它的辅助索引(Secondary Index, 也就是非主键索引)也会包含主键列,所以,如果主键定义的比较大,其他索引也将很大。如果想在表上定义 、很多索引,则争取尽量把主键定义得小一些。InnoDB 不会压缩索引。

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

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

InnoDB索引MyISAM索引的区别:

一是主索引的区别,InnoDB的数据文件本身就是索引文件。而MyISAM的索引和数据是分开的。

二是辅助索引的区别:InnoDB的辅助索引data域存储相应记录主键的值而不是地址。而MyISAM的辅助索引和主索引没有多大区别。

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

  1. mysql优化-------Myisam与innodb引擎,索引文件的区别

    Myisam与innodb引擎,索引文件的区别: innodb的次索引指向对主键的引用. myisam的次索引和主索引都指向物理行. myisam一行一行的插入,会产生一行一行的文件,磁盘上有数据文件 ...

  2. MySQL存储引擎MyISAM和InnoDB,索引结构优缺点

    MySQL存储引擎MyISAM和InnoDB底层索引结构 深入理解MySQL索引底层数据结构与算法 (各种索引结构优缺点) Myisam和Innodb索引实现的不同(存储结构) 存储引擎作用于什么对象 ...

  3. 了解MyISAM与InnoDB的索引差异(转)

    出处原文: 1分钟了解MyISAM与InnoDB的索引差异 数据库的索引分为主键索引(Primary Inkex)与普通索引(Secondary Index).InnoDB和MyISAM是怎么利用B+ ...

  4. MyISAM和InnoDB的索引在实现上的不同

    1 MyISAM只把索引载入内存,数据缓存依赖于操作系统,InnoDB把索引和数据都载入内存缓冲 2 MyISAM数据库中的数据是按照插入的顺序保存,在每个索引节点中保存对应的数据行的地址,理论上说主 ...

  5. MyISAM与InnoDB的索引实现

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

  6. 1分钟了解MyISAM与InnoDB的索引差异

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/z50L2O08e2u4afToR9A/article/details/82111747 <数据 ...

  7. MyISAM与InnoDB的索引差异

    数据库的索引分为主键索引(Primary Index)与普通索引(Secondary Index).InnoDB和MyISAM是怎么利用B+树来实现这两类索引的,又有什么差异呢?一.MyISAM的索引 ...

  8. MyISAM与InnoDB的索引实现区别

    一 MyISAM索引实现 1. 主键索引 MyISAM引擎使用B+树作为索引结果,叶节点的data域存放的是数据记录的地址.下图为MyISAM表的主索引,Col1为主键. 2. 辅助索引 在MyISA ...

  9. MySQL的MyISAM与InnoDB的索引方式

    在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的,本文主要讨论MyISAM和InnoDB两个存储引擎的索引实现方式. MyISAM索引实现 MyISAM引擎使用B+Tr ...

随机推荐

  1. Dynamics CRM 通过OData查询数据URI中包含中文的情况

    filter条件如下"?$filter=new_name eq '采购主管' and new_entityname eq 'new_purchaseenquiry' ",如果用这个 ...

  2. Linux 用户打开进程数的调整

    Linux 用户打开进程数的调整 参考文章: 关于RHEL6中ulimit的nproc限制(http://www.cnblogs.com/kumulinux/archive/2012/12/16/28 ...

  3. anndroid 模糊引导界面

    先上两张图,后面补上代码 我们以前的写法是在需要显示模糊引导的地方,写一个布局,然后第一次使用的时候显示出来.但是这样做代码结构不清晰,所以我们有必要将这些View独立出来,写成一个自定义的View ...

  4. 如何调整DOS窗口的宽高

    运行->cmd->dos窗口上沿点右键->默认值所选字体字体: 新宋体大小: 13窗口大小宽度: 100高度: 40屏幕缓冲区大小宽度: 100高度: 300 在这里还可以设置依他常 ...

  5. 二分算法C实现

    #include <stdio.h> #include <stdlib.h> #define NR(x) (sizeof(x)/sizeof(x[0])) int Binary ...

  6. ruby创建某些“关键字”方法别名的语法

    begin和end是ruby的关键字,但是Range中也有名称为begin和end的实例方法.现在问题来了:怎么创建它们的别名方法? 如果用class Range;alias begin_x begi ...

  7. 基于Redis的分布式锁两种实现方式

    最近有一个竞拍的项目会用到分布式锁,网上查到的结果是有三种途径可以实现.1.数据库锁机制,2.redis的锁,3.zookeeper.考虑到使用mysql实现会在性能这一块会受影响,zookeeper ...

  8. CSS基础:层叠顺序和层叠上下文

    简介 在考虑到两个元素可能重叠的情况下,层叠顺序决定了那个元素在前面,那个元素在后面,这是针对普通元素而言.而层叠上下文和块级格式化上下文 (BFC) 一样,基本上也是由一些 CSS 属性创建的,它单 ...

  9. 《深入理解Java虚拟机》读书笔记2--垃圾回收

    回收哪些内存/对象 引用计数算法 可达性分析算法 finalize()方法 HotSpot实现分析 转载:http://blog.csdn.net/tjiyu/article/details/5398 ...

  10. 信息化建设中的IT规划精要

    IT规划在信息化建设中发挥着"定位"和"导航"的作用,IT规划理论方法更是博大精深,细细讲来,会成为IT版本的"一千零一夜".因此,本文以& ...