浅析MySQL索引

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: 简述MySQL索引索引是一个单独的、存储在磁盘上的数据库结构,它们包含着对数据表里所有记录的引用指针。使用索引用于快速找出在某个或多个列中有一特定值的行,所有MySQL列类型都可以被索引,对相关列使用索引是提高查询操作速度的最佳途径。

简述MySQL索引

索引是一个单独的、存储在磁盘上的数据库结构,它们包含着对数据表里所有记录的引用指针。使用索引用于快速找出在某个或多个列中有一特定值的行,所有MySQL列类型都可以被索引,对相关列使用索引是提高查询操作速度的最佳途径。

MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。MySQL里同一个数据表里的索引总数限制为16个。

以汉语字典的目录页(索引)举例,我们可以按拼音、笔画、偏旁部首等排序的目录(索引)快速查找到需要的字。


创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。

实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。

虽然索引大大提高了查询速度,同时却会降低更新表的速度,比如,对表进行INSERT、UPDATE和DELETE操作。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件,建立索引会占用磁盘空间的索引文件,同时,过多的使用索引将会造成滥用。

总之,索引就是用来提高速度的,但是需要维护索引,从而造成资源的浪费;所以,合理的创建索引是必要的。


索引优缺点

优点

  • 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性
  • 建立索引可以有效缩短数据的查询时间
  • 建立索引可以加快表与表之间的连接
  • 为用来排序或者是分组的字段添加索引可以加快分组和排序速度

缺点

  • 创建索引和维护索引需要时间成本,这个成本随着数据量的增加而加大。
  • 索引需要占用物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
  • 会降低表的增删改的效率,因为每次增删改操作,索引需要进行动态维护,导致时间变长。
  • 如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果。
  • 对于非常小的表,大部分情况下简单的全表扫描更高效;


索引分类

按功能划分

普通索引

最基本的索引,没有任何限制。

CREATE INDEX index_name ON `table_name` (`字段名`);
ALTER TABLE `table_name` ADD INDEX index_name (`column`) COMMENT '普通索引'
复制代码


唯一索引

与"普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值。

CREATE UNIQUE INDEX index_name ON `table_name` (`column`);
ALTER TABLE `table_name` ADD UNIQUE (`column`)
ALTER TABLE `table_name` ADD UNIQUE INDEX (`column`)
ALTER TABLE `table_name` ADD UNIQUE KEY (`column`)
# 指定索引名
ALTER TABLE `table_name` ADD UNIQUE index_name (`column`)
复制代码


主键索引

它是一种特殊的唯一索引,不允许有空值。

ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
复制代码


全文索引

仅可用于MyISAM存储引擎的表,针对较大的数据,生成全文索引很耗时耗空间。

ALTER TABLE `table_name` ADD FULLTEXT ( `column` )
复制代码


按列数划分

单例索引

一个索引只包含一个列,一个表可以有多个单列索引,但这不是组合索引。

组合索引

一个索引包含多个列。为了更多的提高MySQL效率可建立组合索引,遵循”最左前缀“原则。

ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
复制代码


按物理结构划分

聚簇索引

聚簇索引(clustered index)不是单独的一种索引类型,而是一种数据存储方式。

这种存储方式是依靠B+树来实现的,根据表的主键构造一棵B+树,当B+树叶子节点存放的都是表的行记录数据时,方可称该主键索引为聚簇索引。

聚簇索引也可理解为将数据存储与索引放到了一块,找到索引也就找到了数据。

非聚簇索引(有时也称为辅助索引或二级索引)

数据和索引是分开的,B+树叶子节点存放的不是数据表的行记录。

叶子节点中存储主键值,每次查找数据时,根据索引找到叶子节点中的主键值,根据主键值再到聚簇索引中得到完整的一行记录。总之,二级索引访问需要两次索引查找,第一次找到主键值,第二次根据主键值找到行数据。

拓展:聚簇索引优缺点


优点
  • 数据访问更快,因为聚簇索引将索引和数据保存在同一个B+树中,因此从聚簇索引中获取数据比非聚簇索引更快
  • 聚簇索引对于主键的排序查找和范围查找速度非常快
缺点
  • 插入速度严重依赖于插入顺序,按照主键的顺序插入是最快的方式,否则将会出现页分裂,严重影响性能。因此,对于InnoDB表,我们一般都会定义一个自增的ID列为主键(主键列不要选没有意义的自增列,选经常查询的条件列才好,不然无法体现其主键索引性能
  • 更新主键的代价很高,因为将会导致被更新的行移动。因此,对于InnoDB表,我们一般定义主键为不可更新。

虽然InnoDB和MyISAM存储引擎都默认使用B+树结构存储索引,但是只有InnoDB的主键索引才是聚簇索引,InnoDB中的辅助索引以及MyISAM使用的都是非聚簇索引。每张表最多只能拥有一个聚簇索引。


索引存储类型

常用的索引存储类型(索引底层的数据结构)有:B-TREEB+TREEHASH 等,Mysql索引主要有两种结构:B+Tree索引和Hash索引。

B-TREE(B数,多路搜索树)

网络异常,图片无法展示
|


B树是一种多路搜索树,每个节点有多个孩子节点,一棵m阶的B-Tree有如下性质:

  1. 树中的每个节点最多含有m个孩子(m>=2)
  2. 除根节点和叶子节点外,其它每个节点至少有ceil(m/2)个孩子(其中ceil(x)是一个取上限的函数)
  3. 根结点至少有2个孩子,根节点同时是叶子节点的话除外
  4. 所有叶子结点都出现在同一层
  5. 内部节点至少半满
  6. 树内的每个节点都存储数据
  7. 叶子节点之间无指针相邻

它的特点如下:

  1. 保持键值有序,以顺序遍历
  2. 使用层次化的索引来最小磁盘读取
  3. 使用不完全填充的块来加速插入和删除
  4. 通过优雅的遍历算法来保持索引平衡
  5. 通过保证内部节点至少半满来最小化空间浪费
  6. 一棵树可以处理任意数目的插入和删除

网络异常,图片无法展示
|


B+TREE(B+数)

网络异常,图片无法展示
|

B+Tree是B-Tree的一个变种。它与B数的不同之处如下:

  1. 叶子节点存储了所有的关键字信息(数据只出现在叶子节点)
  2. 叶子节点的最后一个指针指向相邻的下一个叶子节点(所有叶子节点增加了一个链指针)

它的特点如下:

  1. 所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的
  2. 不可能在非叶子结点命中
  3. 非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层

网络异常,图片无法展示
|


B树与B+树的区别

  1. B树的树内存储数据,因此查询单条数据的时候,B树的查询效率不固定,最好的情况是O(1)。我们可以认为在做单一数据查询的时候,使用B树平均性能更好。但是,由于B树中各节点之间没有指针相邻,因此B树不适合做一些数据遍历操作。
  2. B+树的数据只出现在叶子节点上,因此在查询单条数据的时候,查询速度非常稳定。因此,在做单一数据的查询上,其平均性能并不如B树。但是,B+树的叶子节点上有指针进行相连,因此在做数据遍历的时候,只需要对叶子节点进行遍历即可,这个特性使得B+树非常适合做范围查询

通常情况下,在关系型数据中,遍历操作比较常见,因此采用B+树作为索引,比较合适,如MySQL。而在非关系型数据库中,单一查询比较常见,因此采用B树作为索引,比较合适,如Mongodb。

HASH

哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可立刻定位到相应的位置,速度非常快。Memory存储引擎默认使用的Hash。

网络异常,图片无法展示
|


MySQL 指定索引类型

一些存储引擎允许您在创建索引时指定索引类型(index_type)。

例如:

CREATE TABLE lookup (id INT) ENGINE = MEMORY; 
CREATE INDEX id_index ON lookup (id) USING BTREE;
复制代码


不同存储引擎支持指定的索引类型

下表显示了不同存储引擎支持的索引类型值。

如果列出了多个索引类型,当没有给出索引类型说明时,第一个是默认值。

表中未列出的存储引擎,在索引定义中,不支持index_type子句。

存储引擎 允许的索引类型
InnoDB BTREE
MyISAM BTREE
MEMORY/HEAP HASH, BTREE
NDB HASH, BTREE


创建索引的准则


应该创建索引的列

  • 经常需要搜索的列上,可以加快搜索的速度
  • 作为主键的列上,强制该列的唯一性和组织表中数据的排列结构
  • 经常用在连接(JOIN)的列上,这些列主要是一外键,可以加快连接的速度
  • 在经常需要根据范围(<,<=,=,>,>=,BETWEEN,IN)进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的
  • 在经常需要排序(order by)的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
  • 经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。

不该创建索引的列

  • 对于那些在查询中很少使用的列不应该创建索引。若列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
  • 对于那些只有很少数据值或者重复值多的列也不应该增加索引。这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。这时候增加索引,并不能明显加快检索速度。
  • 对于那些定义为text, image和bit数据类型的列不应该增加索引。这些列的数据量要么相当大,要么取值很少。
  • 该列修改性能要求远远高于检索性能时,不应该创建索引。(修改性能和检索性能是互相矛盾的)


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
4月前
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
4月前
|
存储 关系型数据库 MySQL
MySQL数据库索引的数据结构?
MySQL中默认使用B+tree索引,它是一种多路平衡搜索树,具有树高较低、检索速度快的特点。所有数据存储在叶子节点,非叶子节点仅作索引,且叶子节点形成双向链表,便于区间查询。
146 4
|
6月前
|
存储 关系型数据库 MySQL
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
|
8月前
|
关系型数据库 MySQL 数据库
Mysql的索引
MYSQL索引主要有 : 单列索引 , 组合索引和空间索引 , 用的比较多的就是单列索引和组合索引 , 空间索引我这边没有用到过 单列索引 : 在MYSQL数据库表的某一列上面创建的索引叫单列索引 , 单列索引又分为 ● 普通索引:MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一点。 ● 唯一索引:索引列中的值必须是唯一的,但是允许为空值 ● 主键索引:是一种特殊的唯一索引,不允许有空值 ● 全文索引: 只有在MyISAM引擎、InnoDB(5.6以后)上才能使⽤用,而且只能在CHAR,VARCHAR,TEXT类型字段上使⽤用全⽂文索引。
|
4月前
|
存储 SQL 关系型数据库
MySQL 核心知识与索引优化全解析
本文系统梳理了 MySQL 的核心知识与索引优化策略。在基础概念部分,阐述了 char 与 varchar 在存储方式和性能上的差异,以及事务的 ACID 特性、并发事务问题及对应的隔离级别(MySQL 默认 REPEATABLE READ)。 索引基础部分,详解了 InnoDB 默认的 B+tree 索引结构(多路平衡树、叶子节点存数据、双向链表支持区间查询),区分了聚簇索引(数据与索引共存,唯一)和二级索引(数据与索引分离,多个),解释了回表查询的概念及优化方法,并分析了 B+tree 作为索引结构的优势(树高低、效率稳、支持区间查询)。 索引优化部分,列出了索引创建的六大原则
108 2
|
5月前
|
存储 关系型数据库 MySQL
MySQL覆盖索引解释
总之,覆盖索引就像是图书馆中那些使得搜索变得极为迅速和简单的工具,一旦正确使用,就会让你的数据库查询飞快而轻便。让数据检索就像是读者在图书目录中以最快速度找到所需信息一样简便。这样的效率和速度,让覆盖索引成为数据库优化师傅们手中的尚方宝剑,既能够提升性能,又能够保持系统的整洁高效。
146 9
|
11月前
|
SQL 关系型数据库 MySQL
深入解析MySQL的EXPLAIN:指标详解与索引优化
MySQL 中的 `EXPLAIN` 语句用于分析和优化 SQL 查询,帮助你了解查询优化器的执行计划。本文详细介绍了 `EXPLAIN` 输出的各项指标,如 `id`、`select_type`、`table`、`type`、`key` 等,并提供了如何利用这些指标优化索引结构和 SQL 语句的具体方法。通过实战案例,展示了如何通过创建合适索引和调整查询语句来提升查询性能。
2176 10
|
6月前
|
机器学习/深度学习 关系型数据库 MySQL
对比MySQL全文索引与常规索引的互异性
现在,你或许明白了这两种索引的差异,但任何技术决策都不应仅仅基于理论之上。你可以创建你的数据库实验环境,尝试不同类型的索引,看看它们如何影响性能,感受它们真实的力量。只有这样,你才能熟悉它们,掌握什么时候使用全文索引,什么时候使用常规索引,以适应复杂多变的业务需求。
138 12
|
10月前
|
存储 关系型数据库 MySQL
MySQL索引学习笔记
本文深入探讨了MySQL数据库中慢查询分析的关键概念和技术手段。
650 81
|
7月前
|
SQL 存储 关系型数据库
MySQL选错索引了怎么办?
本文探讨了MySQL中因索引选择不当导致查询性能下降的问题。通过创建包含10万行数据的表并插入数据,分析了一条简单SQL语句在不同场景下的执行情况。实验表明,当数据频繁更新时,MySQL可能因统计信息不准确而选错索引,导致全表扫描。文章深入解析了优化器判断扫描行数的机制,指出基数统计误差是主要原因,并提供了通过`analyze table`重新统计索引信息的解决方法。
160 3

推荐镜像

更多