MySQL之索引(高级)

MySQL之索引

一 概述

MySQL官方对索引的定义为:
索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据 库系统还维护者满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据, 这样就可以在这些数 据结构上实现高级查找算法,这种数据结构就是索引。如下面的示意图所示 :
补充知识:二叉树存储节点的特定是左小右大,小于节点数据的则放在左边,大于节点数据的则放在右边,
例如查询数据3则需要经过全文检索才能找到,但如果建立索引后想找到数据3则只要查3次就找到了,那么索引又是怎么样找到对应的数据的呢,如图中所示一样,它是通过引用指向数据的。
在这里插入图片描述
左边是数据表,一共有两列七条记录,最左边的是数据记录的物理地址(注意逻辑上相邻的记录在磁盘上也并不是 一定物理相邻的)。为了加快Col2的查找,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和一 个指向对应数据记录物理地址的指针,这样就可以运用二叉查找快速获取到相应数据。

一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在磁盘上。索引是数据 库中用来提高性能的最常用的工具。

二 索引结构

1 索引结构

索引是在MySQL的存储引擎层中实现的,而不是在服务器层实现的。所以每种存储引擎的索引都不一定完全相同,也不是所有的存储引擎都支持所有的索引类型的。MySQL目前提供了以下4种索引:

(1)BTREE 索引 : 最常见的索引类型,大部分索引都支持 B 树索引。

(2)HASH 索引:只有Memory引擎支持 , 使用场景简单 。

(3)R-tree 索引(空间索引):空间索引是MyISAM引擎的一个特殊索引类型,主要用于地理空间数据类型,通常使用较少,不做特别介绍。

(4)Full-text (全文索引) :全文索引也是MyISAM的一个特殊索引类型,主要用于全文索引,InnoDB从Mysql5.6版本开始支持全文索引。


MyISAM、InnoDB、Memory三种存储引擎对各种索引类型的支持

BTREE索引	支持	支持	支持HASH 索引	不支持	不支持	支持R-tree 索引	不支持	支持	不支持Full-text	5.6版本之后支持	支持	不支持

我们平常所说的索引,如果没有特别指明,都是指B+树(多路搜索树,并不一定是二叉的)结构组织的索引。其中聚集索引、复合索引、前缀索引、唯一索引默认都是使用 B+tree 索引,统称为 索引。

2 索引优势与劣势

优势

1) 类似于书籍的目录索引,提高数据检索的效率,降低数据库的IO成本。

2) 通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗。

劣势

1) 实际上索引也是一张表,该表中保存了主键与索引字段,并指向实体类的记录,所以索引列也是要占用空间的。

2) 虽然索引大大提高了查询效率,同时却也降低更新表的速度,如对表进行INSERT、UPDATE、DELETE。因为更新表时,MySQL 不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段,都会调整因为更新所带来的键值变化后的索引信息。

三 BTREE的结构及演示过程

Btree又叫多路平衡搜索树,一颗m叉的Btree有以下特点:
(1)树中每个节点最多包含m个孩子
(2)除了根节点和叶子节点外,每个节点至少有【ceil(m/2)】个孩子
(3)根节点不是叶子节点则至少有2个孩子
(4)所有的叶子节点都在同一层
(5)每一个非叶子节点有n个key与n+1个指针组成,其中[ceil(m/2)-1]<= n <= m-1,当n>m-1时,中间节点分裂为父节点,两边节点分裂为子节点
以5叉数为例,如图所示:
key的数量:2<=n<=4,当n>4,中间节点分裂为父节点,两边节点分裂为子节点
数据为: C N G A H E K Q M F W L T Z D P R X Y S
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四 B+Tree以及MySQL中的B+Tree结构

(1)B+Tree为BTree的变种,两者的区别如下:
① n叉B+Tree数最多含有n个key,BTree最多含有n-1个key
② B+Tree的叶子节点保存所有的key信息,根据key大小顺序排列
③ 所有的非叶子节点的可以看做key的索引部分
B+Tree的结构图如下所示:
在这里插入图片描述

(2)MySQL索引数据结构对经典的B+Tree进行了优化,增加了一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的B+Tree,提高区间的访问性能。
MySQL的B+Tree的结构示意图:
在这里插入图片描述

五 索引的分类

(1)单值索引:即一个索引只包含单个列,一个表不可以有多个单列索引
(2)唯一索引:索引列的值必须唯一,但允许有控制,例如手机号,银行卡号等值必须是唯一
(3)复合索引:即一个索引包含多个列,例如手机号和银行卡号一起,如果一个表中的数据在查询时有多个字段总是同时出现则这些字段就可以作为复合索引

六 索引的语法

1 创建索引

(1)语法

CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX 索引名称
[USING 索引类型]
ON 创建索引的表名(创建索引的字段);

(2)案例

createt index idx_city_name on city(city_name);

2 查看索引

(1)语法

SHOW INDEX FORM 创建索引的表名;

(2)案例

show index from city;

3 删除索引

(1)语法

DROP INDEX 索引名 ON 表名;

(2)案例

drop index idx_city_name on city;

4 ALTER命令创建索引

(1)语法

① alter table 表名 add primary key (字段);添加主键索引,必须唯一且不能为null
② alter table 表名 add unique 索引名(字段);唯一索引可以为null
③ alter table 表名 add index 索引名(字段);添加普通索引,可以出现多次
④ alter table 表名 add fulltext 索引名(字段);添加全文索引

5 索引的使用

(1)全值匹配
对索引中所有列都指定具体指,该情况下,索引生效,执行效率高。
在这里插入图片描述
(2)最左前缀法则(爬楼梯)
如果索引引入多列,要遵守最左前缀法则,查询从索引的最左列开始,并且不跳过索引的列,即包含索引中坐左边的字段(类似于第一楼楼梯)。
在这里插入图片描述
(3)尽量使用覆盖索引(只包含索引列的字段),避免select *而产生回表查询。
在这里插入图片描述
补充点:

using index:使用覆盖索引的时候出现
using where:查找使用索引的时候需要回表查询数据
using index condition:查找使用索引,需要回表查询数据
using index;using where:查找使用索引,但需要的数据在索引列中能找到,不然会回表查询

6 索引失效

(1)范围查询,右边的列索引失效
在这里插入图片描述

(2)在索引列使用运算操作,索引失效
在这里插入图片描述
(3)字符串类型不加单引号,索引失效
在这里插入图片描述
(4)or索引失效
在这里插入图片描述
(5)like "**%**条件"索引失效
在这里插入图片描述
使用覆盖索引解决模糊的索引失效问题
在这里插入图片描述
(6)null与is null索引有时失效,有时不失效,主要看表数据,如果数据量大部分有值,则null走索引,若大部分为null走is null的索引
(7)in走索引,not in 索引失效
在这里插入图片描述

七 索引的设计原则

(1)对查询频次较高且数据量较大的表建立索引
(2)索引字段最佳候选列为从where子句的条件中获取,若where子句中的组合较多,则选择常用、过滤效果最好的列的组合成为复合索引
(3)使用唯一索引,区分度越高,使用索引的效率越高
(4)索引并不是多多益善的,索引越多,对应插入、更新、删除等DML操作比较频繁的表来说,会增加维护代价,降低DML操作的效率。
(5)使用短索引,索引创建后是使用硬盘来储存的,提升索引访问的IO效率可以提升总体的访问效率,索引字段比较短,那么给定大小的存储块就可以存储更多的索引值,达到提升mysql访问IO的效率。
(6)利用最左前缀,N个列组合而成的组合索引就相当于创建了N个索引,当where子句用到组合索引的字段时就会提升查询效率。
例如:

创建复合索引:
create index idx_name_email_status on tb_seller(name,email,status);
相当于:
	对name创建索引;
	对name,email创建索引;
	对name,email,Status创建索引;

猜你喜欢

转载自blog.csdn.net/hcyxsh/article/details/114787376