对于MYSQL索引的一些理解

来源:互联网 发布:uc高达 知乎 编辑:程序博客网 时间:2024/06/15 03:14

同样是基于昨天的一道面试题,面试官先是问了下MYSQL的索引是什么结构,我随口就说是B+树的索引,然后他接着追问,B+树索引的特点是什么,然后,就没有然后了。。

其实,对于MYSQL的索引部分,我之前是看过书的,《MySQL技术内幕 InnoDB存储引擎 第2版》这本书,我下载了电子版,花平时上班之余基本上从头看到尾了,也记了些笔记 ,但那是一个月之前的事。没想到用的时候,完全记不起来了。为什么呢?毫无疑问,记忆力太差,而且只看了一次。所以今天又找出那本书再看了一下,当然还是没有完全搞清楚,但不至于像昨天那样,什么话都说不出来。

要回答面试官的这个问题,个人认为,首先要搞清楚这样一些前提:

  • 什么是索引?索引可以分为哪几类?
  • 什么是二叉查找树,什么是平衡二叉树?什么是B+树?
  • 不同的存储引擎,其索引实现有什么区别?

我尝试着按自己的理解,结合所看的书,来回答上面的问题。

首先,索引的存在是为了提高数据检索的效率,通常的一个比喻,是将索引比喻成一本书的目录,如果你知道某篇文章名在目录的话,那么我们可以先通过目录找到该文章对应的页码,直接找到该页码即可,而没有目录,很可能我们要一页面的翻,才能找到我们要的文章。索引也是这样。MYSQL中,INNODB和MYISAM都采用了B+树的结构来实现索引,当然,还有别的索引实现方式,比如HASH索引,但我们主要关注B+树索引。

了解B+树,我们就需要先了解二叉查找树和平衡二叉树,二叉树的定义很简单,一个节点最多只能有两个子树,而且每个节点的值,都大于其左子树的值,小于或等于其右子树的值。那么对于这个树的查找,可以很方便地用二分法来进行。同样,如果按照中序的方式对这个数进行遍历的话,结果将会是一个有序的序列。

二叉树可能是偏向一边的,即可能没有左子树,或者没有右子树,这样的话,查找并不能提高效率,所以,有了平衡二叉树的概念,平衡,表示左右树的深度差不能超过1,这就避免了一边倾斜的可能。

B+树的定义远比上面两种复杂,具体就不说了,但也类似有平衡二叉树的性质,只是子树不止两个。应用到MYSQL中,应该有以下一些特点。

  • 数据都存在于叶子节点
  • 索引都存在于非叶子节点
  • 如果是INNODB的聚簇索引,则叶子节点存储的就是实际的数据信息,如果是非聚簇索引,则存储的是主键的值。
  • 如果是MYISAM的索引,则叶子节点存储的是数据的地址。

从上面的说明又引申出了几个概念,首先,我们来解释一下聚簇索引,这个应该是INNODB专有的,指的是主键对应的索引,其特点就在于叶子节点存储的就是实际的数据信息,所以,如果我们根据主键进行查询的话,将会很方便地取到对应的数据。这也从另外一个方面说明了,INNODB的索引和数据文件是存在一起的,都存储于表空间。

由此推论,INNODB的每张表有且只有一个聚簇索引,那么问题来了,如果我们在创建表的时候没有定义主键呢?这个时候,MYSQL会帮我们创建一个rowid,6个字节。而事实上,我们如果用int来做主键的话只占用4个字节,所以一般情况下,我们要显示定义主键。

非聚簇索引也称为辅助索引,由于其叶子节点存储的是主键的值,所以,如果我们按辅助索引查找的话,实际上是需要查两次,先找到主键的值,再根据主键找数据。对于MYISAM来说,主键和非主键则不存在这个区别,查找都是先找到地址,再根据地址读数据。它们的区别只是在于主键的KEY是惟一的。

如果索引由多个字段组成,我们称这类为联合索引,对于联合索引i_k(a,b)来说,形如where a=x and b=x, where a=x都可以用到索引,而where b=x则用不到,为什么呢?因为关键字是先按a排序,再按b排序的。

如果要查找的列本身就是索引,则我们称其为覆盖索引,由于要查的数据就是索引的KEY,所以不需要查找两次。

如果我们要看一个索引是否使用到,可以使用explain来分析
最后,贴一下之前遇到的一次面试题 ,请问<,>,<>这三种操作是否会用到索引?

个人认为,对于B+树索引来说,应该是都可以用到,而对于HASH索引来说,由于HASH的特点,无法用于范围查询。

0 0
原创粉丝点击