InnoDB引擎索引大观

三只松鼠

InnoDB是mysql处理OLTP(online transcation process)类型业务的存储引擎。为了加快数据查询速度,InnoDB引擎提供了丰富的索引实现。

1. 索引的分类

索引可以分为聚集索引和非聚集索引,聚簇索引(cluster) index)是指索引中键值的逻辑顺序和相应行的物理顺序一致,简单说就是索引中键值存储的是对应的行数据。非聚簇索引中索引的键值中存储的只是相应行的引用,并不代表行实际的存储。索引是在数据库的存储引擎中实现,不同的存储引擎索引的实现不一样。举例来说,你翻到新华字典的汉字“爬”那一页就是P开头的部分,这就是物理存储顺序(聚簇索引);而不用你到目录,找到汉字“爬”所在的页码,然后根据页码找到这个字(非聚簇索引)[1]。

根据实现方式的不同,索引分为B+树索引、哈希索引、全文索引和空间树索引。B/B+树是实现索引常用的数据结构。它是一个平衡的多叉查找树,从根节点到每一个叶子节点的距离相等且树的高度可控,因此能够大幅度的减少查找次数。哈希是一种非常快的查找方法,一般情况下查找的时间复杂度为O(1),但是很多的数据库系统如SQL Server、Oracle并不支持哈希索引。MySQL的Memory存储引擎默认的存储类型为哈希。而在InnoDB数据库引擎实现了一种自适应性哈希索引。InnoDB引擎会监控对索引表上索引的查找,如果观察到建立哈希索引可以带来速度的有效提升,则建立哈希索引。自适应性索引通过缓冲池的B+树构建而来,因此建立速度很快。全文索引是使用类似倒排索引的结构构造而成,MySQL中可以在建表时指定FULLTEXT到nchar,vchar,text类型性的字段上建立全文索引。


2. MyISAM和InnoDB索引实现的不同

***

聚簇索引保证关键字的值相近的元组存储的物理位置也相同(所以字符串类型不宜建立聚簇索引,特别是随机字符串,会使得系统进行大量的移动操作),且一个表只能有一个聚簇索引。因为由存储引擎实现索引,所以,并不是所有的引擎都支持聚簇索引。目前,只有solidDB和InnoDB支持。

叶子页面包含完整的元组,而内节点页面仅包含索引的列(索引的列为整型)。一些DBMS允许用户指定聚簇索引,但是MySQL的存储引擎到目前为止都不支持。InnoDB对主键建立聚簇索引。如果你不指定主键,InnoDB会用一个具有唯一且非空值的索引来代替。如果不存在这样的索引,InnoDB会定义一个隐藏的主键,然后对其建立聚簇索引。一般来说,DBMS都会以聚簇索引的形式来存储实际的数据,它是其它二级索引的基础。

MyISAM只支持非聚簇的索引,因此在谈主键索引和辅助索引之间的区别的时候不能简单的一概而论,比较合适的说法应该是这样的:

索引的功能是在存储引擎上存在的,不同的存储引擎实现主键索引和辅助索引不同。在MyISAM存储引擎中,主键索引和非逐渐索引都是非聚簇索引,叶子节点都是存储对应数据行的引用。而在InnoDB中,主键索引是聚集索引,B+树的叶子节点存储是行数据。辅助索引是非聚集索引,索引B+树叶子节点存储的对应行的主键,通过主键索引可以找到相应的行。
另外InnoDB支持自适应哈希索引,MyISAM支持全文索引。MySQL 5.6以后的InnoDB存储引擎也开始支持全文索引。

3. 使用索引的几个原则

索引能够减少查询的次数,但是一个错误的观点是在每一个可能的属性上都建索引。索引的建立和调整过程会消耗资源。与索引对应的全表查找,如果表中数据的数量很少建索引其实是不合适的。那什么情况下使用索引才更有效呢?

B+树索引使用的两个原则:

  1. 高选择性
  2. 结果集的数量很少的情况

如果某个字段取值范围很广(性别和地域字段就是一个返利),几乎没有重复,即高选择性,则此时使用B+树索引是最合适的。

如果结果的数量很多通过B+树索引一层层判断的性能差于全表扫描。即使你在该列加了索引,优化器也不会使用索引,而是会使用全表扫描的方法。

对于第二种情况,优化器是怎么判断是不是应该使用索引的呢?优化器会通过EXPLAIN的row字段预估查询可能得到的行,如果大于20%的行优化器会使用全表扫描的方法。

实际上,预估的返回行数的值是不准确的,因此优化器有时是不靠谱的。
如果我们能够明确知道返回的结果集的大小,可以使用force index(index_col)强制使用索引。

3.1 索引失效的情况

B+树索引失效实质是查询不适用B+树查找的性质。常见的情况有: (1)后项或者中间匹配,例如:使用like ‘a%*’是可以使用索引,使用like ‘%*a’ 索引失效 (2)使用IS NOT NULL或者<> (3)在索引列上使用函数或者运算 (4)复合索引中where条件没有使用到第一列,例如:where A=1或者where A=1 and B=2都会使用到索引,where B=2或者where A=1 or B=2索引失效.
<h1>4 主键索引和辅助索引</h1>
<h1>5 复合索引 </h1>

参考文章:
[1] http://blog.chinaunix.net/uid-116213-id-3395051.html

发布了53 篇原创文章 · 获赞 16 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/gexiaochuan122/article/details/47079545
今日推荐