MySQL的索引

(1)索引概述

索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查询算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。

索引的优点:

提高数据检索的效率,降低数据库的IO成本,通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗。

索引的劣势:

索引列也是要占用空间的,索引大大提高了查询效率,同时却也降低更新表的速度,如对表进行INSERT、UPDATE、DELETE时,效率也降低。

(2)索引结构

MySQL的索引是在存储引擎层实现的,不同的存储引擎有不同的结构,主要包含以下几种:

B+Tree索引:最常见的索引类型,大部分引擎都支持B+Tree索引

Hash索引:底层数据结构是用哈希表实现的,只有精确匹配索引列的查询才有效,不支持范围查询

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

Full-text(全文索引):是一种通过建立倒排索引,快速匹配文档的方式。

二叉树缺点:顺序插入时,会形成一个链表,查询性能大大降低,大数据量情况下,层级较深,检索速度慢;

红黑树:大数据量情况下,层级较深,检索速度慢。

B-Tree(多路平衡查找树):以一颗最大度数(max-degree)为5(5阶)的B-Tree为例(每个节点最多存储4个key,5个指针)

B-Tree的演变过程

B-Tree的演变过程: https://www.cs.usfca.edu/~galles/visualization/BTree.html

B+Tree:所有的元素都会存放在叶子节点;叶子节点形成一个单向链表;非叶子节点只起到索引的作用。

以一颗最大度数(max-degree)为4(4阶)的B+Tree为例

MySQL的B+Tree结构

MySQL索引数据结构对经典的B+Tree进行了优化。在原B+Tree的基础上,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的B+Tree,提高区间访问的性能。

MySQL中,页的默认大小时16KB。

为什么InnoDB存储引擎选择使用B+Tree索引结构

(a)相对于二叉树,层级更少,搜索效率高;

(b)对于B-Tree,无论是叶子节点还是非叶子节点,都会保存数据,

这样导致一页中存储的键值减少,指针跟着减少,要同样保存大量

数据,只能增加树的高度,导致性能降低。

(c)相对Hash索引,B+Tree支持范围匹配和顺序操作。

(3)索引分类

主键索引:针对于表中主键创建的索引,默认自动创建,只能有一个;关键字:PRIMARY

唯一索引:避免同一个表中某数据列中的值重复,可以有多个;关键字:UNIQUE

常规索引:快速定位特定数据,可以有多个;

全文索引:全文索引查找的是文本中的关键词,而不是比较索引中的值,可以有多个。 关键字:FULLTEXT

在InnoDB存储引擎中,根据索引的存储形式,又可以分为以下两种:

聚集索引(Clustered Index)将数据存储与索引放到了一块,索引结构的叶子节点保存了行数据。必须有,而且只有一个。

二级索引(Secondary Index)将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键。可以存在多个。

聚集索引的选取规则:

(a)如果存在主键,主键索引就是聚集索引。

(b)如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引。

(c)如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引。

聚集索引的叶子节点保存的是行数据。

(a)以下SQL语句,哪个执行效率高

select * from user where id=10;

select * from user where name='Arm';

备注 id为主键,name字段创建的有索引;

(b)InnoDB主键索引的B+Tree高度为多高呢?

假设:一行数据大小为1k,一页中可以存储16行这样的数据,InnoDB的指针占用6个字节的空间,主键即使为bigint,占用字节数为8。

假设高度为2:

n*8+(n+1)*6=16*1024, 算出n约为1170; 所以有1171个指针;

可以存储的行数为: 1171 * 16 = 18736;

假设高度为3:

可以存储的行数为: 1171 * 1171 * 16 = 21939856

(4)索引语法

创建索引:

CREATE [UNIQUE | FULLTEXT] INDEX index_name ON table_name(index_col_name, ...);

查看索引:

SHOW INDEX FROM table_name;

删除索引:

DROP INDEX index_name ON table_name;

表tb_user结构及数据如下:

当前表中的索引:

  1. name字段为姓名字段,该字段的值可能会重复,为该字段创建索引。

create index idex_user_name on tb_user(name);

创建之后,查看表中的索引:show index from tb_user;

  1. phone手机号字段的值,是非空,且唯一的,为该字段创建唯一索引。

create unique index idx_user_phone on tb_user(phone);

查看创建的索引 show index from tb_user;

  1. 为profession、age、status创建联合索引。

create index idx_pro_age_sta on tb_user(profession, age, status);

查看创建就的索引: show index from tb_user;

  1. 为email建立合适的索引来提升查询效率。

create index idx_user_email on tb_user(email);

查看创建的索引: show index from tb_user;

相关推荐
m0_692540071 小时前
数据库表设计规范
数据库·oracle
Coder_Boy_1 小时前
【人工智能应用技术】-基础实战-环境搭建(基于springAI+通义千问)(二)
数据库·人工智能
云贝教育-郑老师2 小时前
【OceanBase OBCE V3.0认证】
数据库·oceanbase
思成不止于此4 小时前
【MySQL 零基础入门】DDL 核心语法全解析:数据库与表结构操作篇
数据库·笔记·学习·mysql
韩立学长4 小时前
【开题答辩实录分享】以《自选便利店商品分类管理系统》为例进行选题答辩实录分享
java·mysql·web
aspirestro三水哥4 小时前
2.5构建Xenomai测试与演示镜像
数据库·rtos·xenomai
随机昵称_1234564 小时前
postgresql连接报错Invalid SCRAM client initialization
数据库·postgresql
Fuly10245 小时前
langchain基础教程(6)---构建知识库--②向量数据库-milvus
数据库·langchain·milvus
TDengine (老段)5 小时前
TDengine IDMP 产品路线图
大数据·数据库·人工智能·ai·时序数据库·tdengine·涛思数据