您的位置:首页 > 数据库 > MySQL

MySQL索引基础

2016-06-15 15:03 316 查看
MySQL的索引有很多类型,索引是在存储引擎层而不是服务层实现的,不同存储引擎的索引实现方式可能是不一样的。

MySQL支持的索引类型主要有:B-Tree索引,哈希索引,全文索引等。

一. B-Tree索引

当谈论索引的时候,如果没有特别指明类型,那多半说的就是B-Tree索引。底层的存储引擎可能使用不同的存储结构来实现该索引,如InnoDB用的B+树来实现的。

B-Tree索引意味着所有值都是按顺序存储的,并且是以多叉排序树的形式存储,即B+树。

B树索引是一个典型的树结构,其包含的组件主要是:

叶子节点(Leaf node):包含条目直接指向表里的数据行。

分支节点(Branch node):包含的条目指向索引里其他的分支节点或者是叶子节点。

根节点(Root node):一个B树索引只有一个根节点,它实际就是位于树的最顶端分支节点。

下图绘制了一个分支节点和其对应的叶子节点,在根节点和叶子节点之间可能存在很多层节点页。

树的深度和表的大小直接相关。



B-Tree索引是从B+树的根节点开始进行搜索。根节点的槽中存放了指向孩子节点的指针,存储引擎根据这些指针向下层查找。通过比较节点页的值和要查找的值可以找到合适的指针进入下层孩子节点,节点页中的值即key。

叶子节点比较特别,它们的指针指向的是被索引的数据。

假设有如下数据表:

包含
last_name, first_name, birthdate, gender
等字段,表的key为
last_name, first_name, birthdate
。因为MySQL会为主键创建索引。所以索引中包含了
last_name, first_name, birthdate
列中的值。下图显示了该索引是如何组织数据的存储的。



二.哈希索引

哈希索引是基于哈希表实现的,只有精确匹配索引所有列的查询才有效。对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码,哈希索引将所有的哈希码存储在索引中,同时在哈希表保存指向每个数据行的指针。

在MySQL中,只有Memory引擎显式支持哈希索引。如果多个列的哈希码相同,索引会以链表的方式存放多个记录指针到同一个哈希索引条目中,即采用链地址法解决哈希冲突。

下面来看一个例子,假设有如下表:

CREATE TABLE testhash(

fname VARCHAR(50) NOT NULL,

lname VARCHAR(50) NOT NULL,

KEY USING HASH(fname )

)ENGINE=MEMORY;

表中包含以下数据:

fname lname

Arjen Lentz

Baron Schwartz

Peter Zaitesv

Vadim Tkchenko

假设索引使用假想的哈希函数f(),它返回下面的值

f(‘Arjen’) = 2323

f(‘Baron’) = 7437

f(‘Peter’) = 8784

f(‘Vadim’) = 2458

则哈希索引的数据结构如下:

槽 值

2323 指向第1行的指针

2458 指向第4行的指针

7437 指向第2行的指针

8784 指向第3行的指针

注意每个槽的编号是顺序的。现在来看如下查询:

SELECT lname FROM testhash WHERE fname=’Peter’;

MySQL先计算‘Peter’的哈希值,即8784,所以在索引中查找8784,可以找到第3行指针。最后一步是比较第三行的值是否为‘Peter’,以确保就是要查找的行。需要最后一步的原因是因为如果有哈希冲突存在,则需要依次遍历链表。

因为哈希索引自身只需要存储对应的哈希值,所以索引结构十分紧凑,这也让哈希索引查找的速度非常快,即O(1)。

然而,哈希索引也有其限制:

1. 不支持部分索引列匹配查找,因为哈希索引始终是使用索引列的全部内容来计算哈希码的。

2. 哈希索引只支持等值比较查询,包括=,IN,也不支持任何范围查询。

3. 如果哈希冲突很多的话,一些索引维护操作也会很高。

因为这些限制,哈希索引只适用于某些特定场合。

三.全文索引

全文索引是一种特殊类型的索引,它查找的是文本中的关键词,而不是直接比较索引中的值。全文索引更类似于搜索引擎做的事情,而不是WHERE条件匹配。

四. 索引的优点和缺点

数据库索引好比是一本书前面的目录,索引就是为加快对表中记录的查找或排序而对某些字段中的值建立的目录。

优点:

1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。

2. 可以大大加快数据的检索速度,这也是创建索引的最主要的原因。

3. 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序时间。

缺点:

1. 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。

2. 索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间。

3. 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: