【MySQL】索引

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 哈喽,大家好~我是保护小周ღ,本期为大家带来的是 MySQL 数据库中表的索引,详细得讲解了索引得基本概念,使用场景,如何添加索引,删除索引,展示索引,以及索引背后的数据结构,确定不来看看~更多相关知识敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★*

一、索引

1.1 索引的概念

当我们是使用查询语句对表中的数据进行条件查询的时候,MySql 服务器会对该表中的数据进行条件遍历,即每一条记录都会判断,时间复杂度是 O(N)。

当我们涉及到多表联合查询时,多表数据就会形成一个笛卡尔积——数据库中的数据都是以二维表的形式存放的,记录就是表格的行,字段就是其中的每个列, 笛卡尔积就是把多个表中的所有数据进行(全部预设的组合),举个例子:

学生表 stu:

成绩表:grade

我们对这两张表进行联合查询。

这里博主展示了全部字段,所以两个表中的数据有所重复,这里使用 Right Join 进行右连接,on 后面是连接匹配的条件,right join 以左表(学生表)为主,在右表(成绩表)中根据匹配条件查找,例如:成绩表中的 id 字段需要和学生表中的 id 字段有所匹配,左表中有符合条件的数据就返回数据与右表进行组合。

这是建立在我们设置了连接条件的基础上,如果我们没有设置条件,两张表就会生成笛卡尔积。

由上图可见,笛卡尔积就是将两张表的数据进行无规则的排列组合,即使数据是错误的,也会排列出来,当我们设置了条件进行条件查询,就会在笛卡尔积中遍历寻找符合条件的数据,形成一张新的数据集合返回客户端,展示给用户,笛卡尔积有多少行记录,取决于,多表中有多少条记录,即: stud 表中记录数 和 grade 表中记录数的乘积,这两张表才只插入了3行记录,笛卡尔积就有9 行, 如果两表中各有 100条记录, 笛卡尔积就有 100 * 100 (10000)行记录,在这种情况下,遍历查询的效率就非常低了。


创建索引的目的就是为了能够快速的定位、检索数据,索引我们可以先理解为是根据字段创建的指向对应记录的指针。

如果搜索条件的列上已经创建了索引,MySQL服务器无需扫描任何记录即可迅速得到目标记录所在的位置。


1.2  索引的运用

索引的创建使用需要考虑一些情况:

索引一般创建于数据量特别大的情况下 索引可以针对一列或者是多列创建,创建于需要经常对这些列进行条件查询的字段,例如 :学号 id 创建索引会占用额外的存储空间,服务器需要组织管理索引 创建索引的列必须能够进行比较,幸运的是 Mysql 提供的数据结构都能够比较。

1.2.1 索引的创建

当我们对数据表的字段创建主键约束 (PRIMARY KEY),唯一约束 (UNIQUE), 外键约束(FOREIGN)的时候,会自动的为这些字段创建索引, 这些字段也是常常被我们用来作为查询条件。

以下是在创建 (create)数据表时建立约束,当数据表创建完毕后,可以使用 ALTER 语句修改(不建议使用 ALTER 语句)。

对字段建立主键约束:

【字段名】 数据类型 primary key

对字段建立外键约束:

foreign key 【字段名】references 【主表】(主键字段或者唯一字段)

对字段建立唯一约束:

【字段名】 数据类型 unique

1.2.2 查看表的索引

show index from 【表名】

1.2.3 创建索引

针对并非 主键、外键、唯一约束的字段,创建索引

create index 索引名 on 【表名】(字段名)

举个例子: 为学生表的 sex 字段设置 引索

mysql>select*from stud;+--------+--------+------+| stu_id | name   | sex  |+--------+--------+------+|1| 张三   |||2| 李四   |||3| 王六   ||+--------+--------+------+3 rows inset(0.00 sec)mysql>create index gender on stud(sex);Query OK,0 rows affected (0.02 sec)Records:0  Duplicates:0  Warnings:0mysql> show index from stud;+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+|Table| Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed |Null| Index_type | Comment | Index_comment |+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+| stud  |0| PRIMARY  |1| stu_id      | A         |3|NULL|NULL|| BTREE      |||| stud  |1| gender   |1| sex         | A         |2|NULL|NULL| YES  | BTREE      |||+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+2 rows inset(0.00 sec)

以上是建立在数据表已经创建好的情况下,在创建数据表的时候可以直接为字段创建约束。

创建一个学生表 stu2 ,有 id ,name, sex 字段,并为 id 字段创建 索引。

mysql>createtable if not exists ()->;ERROR 1064(42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '()' at line 1mysql>createtable if not exists stud2 (-> id int,-> name varchar(20),-> sex varchar(3),-> index(id));Query OK,0 rows affected (0.02 sec)mysql> show index from stud2;+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+|Table| Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed |Null| Index_type | Comment | Index_comment |+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+| stud2 |1| id       |1| id          | A         |0|NULL|NULL| YES  | BTREE      |||+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+1 row inset(0.00 sec)

1.2.4 删除索引

drop index 【索引名】 on 【表名】

删除刚刚 为 stud 学生表 sex 字段创建的名为 gender 的索引

mysql>drop index gender on stud;Query OK,0 rows affected (0.01 sec)Records:0  Duplicates:0  Warnings:0mysql> show index from stud;+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+|Table| Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed |Null| Index_type | Comment | Index_comment |+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+| stud  |0| PRIMARY  |1| stu_id      | A         |3|NULL|NULL|| BTREE      |||+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+1 row inset(0.00 sec)

1.2.5 总结

我们创建索引有4种方式:

  1. 为表中的某些字段设置 主键,外键,唯一约束
  2. 使用 create index 索引名 on 【表名】(字段名) 语句
  3. 可以在创建数据表的时候 使用index(字段)创建索引
  4. 可以使用 ALTER 语句创建索引,也可以给字段添加主键,外键等,只不过是其他的语法,感兴趣的朋友可以观看博主的另一篇博客,表的基本数据类型及表的处理
ALTER TABLE table_name ADD INDEX index_name (column_list);

注意:我们创建索引的时候,或者是主键,尽量提前设计好表的结构,在创建表的时候就把这些约束啥的弄好,或者是在表刚刚创建完毕,还没有插入数据的时候 使用 ALTER 语句对表的结构进行修改,不建议在有很多数据的时候给字段添加索引,因为当数据量过多的时候创建索引对空间和时间开销很大,比如说几百万数据建立索引,系统需要分配大量的资源来存储和管理索引,就会引起数据库的卡顿或者是崩溃。

创建索引的目的就是为了加快MySql 服务端对数据检索的效率,当然这是建立在条件查询的基础之上,主要就是对我们经常作为查询条件的字段创建索引是比较好的选择,索引虽好,需要我们能够把握好他的使用场景,从某种意义上来说创建索引的开销也是很大的。


二、索引底层的数据结构

管理索引底层的数据结构是 B+ 树,说起 B+树,不知道有没有朋友了解过 二叉搜索树呢, B + 树是 B树的基础上做的优化改进, 可以理解为他们是 N 叉搜索树,

B+ 树的特点

key 值——创建索引得字段值

  1. 一个节点可以存储 N个 key值, N 个key 值划分出 N 个区间 (一个key 值划分一个区间)
  2. 每个节点中key 的值(父),会作为子节点的最大值出现在子节点中
  3. B + 树的叶子节点依次链接,类似于一个链表的结构
  4. 因为每个key 值都会划分出 N 个区间,每个key 值都会以最大值的形式在子节点中出现,所以

B+ 树的叶子节点就包含了所有的 key 值,我们也只需要在叶子节点中存储数据表中每一行的数据。


为什么会使用B+ 树作为索引的底层结构呢

B+ 树的实质是 N叉搜索树,相对于二叉搜索树来说,一个节点可以保存更多的 Key ,树的高度会相对来说低,所以查询的效率更高,这就意味着降低了对硬盘的访问次数,MySql 本身就是依托于硬盘存储,数据总归是会被读取到内存中处理的。

B+ 树的叶子节点相互构成链表,适合进行范围查询,找到了指定的 Key 值,Key 值得前后就是范围,顺着指针遍历。

B+ 树叶子节点存储了每一条记录,非叶子节点只需要存储 key 值(创建索引得字段值),所以非叶子节点所占得存储空间比较少,也可以降低硬盘访问数据量。


到这里,Mysql 系列索引相关的知识博主已经分享完了,希望对大家有所帮助,如有不妥之处欢迎批评指正。


下一期:MySQL  数据库事务

感谢每一个观看本篇文章的朋友,更多精彩敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★*

遇见你,所有的星星都落在我的头上……

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

热门文章

最新文章

推荐镜像

更多