MySQL 下索引的分类(一)|学习笔记

简介: 快速学习 MySQL 下索引的分类(一)

开发者学堂课程【MySQL 实操课程:MySQL 下索引的分类(一)】学习笔记,与课程紧密联系,让用户快速学习知识。  

课程地址:https://developer.aliyun.com/learning/course/717/detail/12821


MySQL 下索引的分类(一)

 

内容简介:

一、 索引的分类

二、 普通索引

三、 唯一索引

 

一、索引的分类

两种分类的维度:

1、按索引字段个数分类

(1)单列索引:即一个索引只包含单个列(就是一个字段),一个表可以有多个单列索引,但这不是组合索引。

注意:不要以为有多个单列就是组合索引,其实它是多个单列索引。多个列之间是没有关系的,每个列中有一个单独的索引。

(2)组合索引:即一个索包含多个列,最左前缀法则 abc 建立索引相当于 a,ab,abc 建立索引,被称为组合索引,也叫复合索引。

2、按类型分类

(1)普通索引

(2)唯一索引

(3)主键索引

(4)全文索引

下面进行展开详细的讲解。

 

二、普通索引

1、概念

where , order by , group by 中经常使用的字段,创建索引,可以加快查询速度

图片1.png

举例如上图:

在类型中,图中红色箭头指到的类型就是一个索引,没有包含其他关键字,就是一个 INDEX 关键字,这个关键字就是一个普通的索引,那么像这种普通的索引,它是没有一些其他要求的,只需要给索引指定索引名称和索引对应的关联字段,对索引的字段没有别的要求,既不要求字段的值在表中是唯一的,也不要求一定是主键,一般在创建索引时,会在 where , order by , group by 中经常使用的字段进行创建索引,可以加快查询速度。

2、explain 语句进行索引查询

explain 语句,可以查看 sql 查询情况,是否使用了索引

(1)概况:创建索引的过程中,索引是否被运用是需要考虑的问题,可以使用explain 语句,可以查看sql查询情况,是否使用了索引;  explain 实际上是一个查看MySQL 中的 sql 语句执行情况的命令。(2)下面进行简单的演示:

①复制公网 IP

首先,打开 RDS 管理控制台,然后,回到云服务器管理控制台复制公网 IP

②进行数据库连接

紧接着,通过公网 IP 在 Cloud Shell中,输入 ssh root@47.112.159.55 运行,并输入密码,得到如下:

shell@Alicloud:~ssh root@47. 112.159.55

root@112.159.55’s password:

last login:Thu Aug

在这里面之前有用到,使用命令访问 mysql 中 bin 下面的 mysql,这里直接连接本地安装的 (-uroot), 就不需要输入 -h;输入密码,如:

[root@iZwz9bize6nk8hug8jOvywZ ~]# /usx/local/mysql/bin/mysql -uroot -p

Enter password:

Welcome to the MysQL monitor. Commands end with ; or \g.

Your MySQL connection id is 2

Server version: 5.7.31 MySQL Comeunity Server (GPL)

Copyright (C) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. other names ay be trademarks of their respect ive

Owners.

Type "help;' or '\h' for help. Type '\c' to clear the Current input statement .

之前在这里有一个叫 aliyun 的测试数据库,执行 use aliyun; 命令得到以下:

mysql> use aliyun;

Reading table information for completion of table and column names

You Can turn off this feature to get a quicker startup with -A

Database changed

使用 show tables; 命令显示出里面的表,如:

mysql> shom tables;

Tables_in_aliyun 1

dept

emp

user

user_bak

4 rows in set (0.00 sec)

③不加索引的情形

为了不影响之前的,可以在这里创建字段或表,使用 create table school(id int,name varchar(20)); 命令创建一个有 id 和 name 的 school 表,这是不加索引的情形,如:

mysql> create table school(id int , naime varchar (20));

Query OK, 0 rows affected (0.01 sec)

使用 insert into school values(1001,’yizhong’);命令插入 id 为1001,name 为yizhong 的数据,如:

mysql> insert into school values (1001, 'yizhong');

Query OK, 1 row affected (0. 00 sec)

使用 select * from school; 命令进行查询,得出一条数据,如:

mysql> select . from school;

id        name

1001    yizhong

row     in set (0.00 sec)

使用 insert into school values(1002,’erzhong’);和 insert into school values(1001,’sanzhong’);命令插入两条数据,再使用 select * from school; 命令进行查询,得到三条数据,如:

mysql> insert into school values (1002, 'erzhong');

Query OK, 1 row affected (0.00 sec)

mysql> insert into school values (1003, 'sanzhong');

Query OK, 1 row affected (0.00 sec)

mysql> select from school;

id     name

1001  yi zhong

1002  erzhongI

1003  sanzhong

3 CONS in set (0.00 sec)

使用explain select * from school where id=1001; 命令查看是否运用到索引,如:

mysql> explain select * from school where id=1001;

+----+------------+-------+-----------+-----+--------------+---…

|  id | select_type | table  | partitions | type | possible keys | key…

|   1| SIMPLE     |school | NULL    |ALL  |NULL        |NUL…

+----+------------+-------+-----------+-----+--------------+---…

1 row in set, 1 warning (0.00 sec)

这里打印出来的信息,select_type 为 SIMPLE,代表它是一个单表;table 是指定查询的表名; partitions为NULL,代表分区是没有的;type 为 ALL, 这个 ALL 就说明它没有运用索引,代表的是全表扫描,就是在查询 id=1001 这条数据的时候,它做了一个全表扫描的动作,所以它没有运用索引;rows 代表当前扫描的行数。

④加索引的情形

使用 create table school_index(id int,name varchar(20),index

(id)); 命令创建一个以 id 为索引的表,如:

mysql> create table school index (id int Dame varchar (20),index (id));

Query OK, 0 EONS affected 0.02 sec)

然后进行查看信息,可以看到表名为 school_index,里面有一个索引,如:

mysql> show indexes from school_index;

使用 insert into school_index select * from school; 命令把 school 表中的三条数据插入到 school_index 表中,如:

mysql> insert into school index select . from school;

再进行查看数据,如:

mysql> select * from school_index;

|  id | name        |

|1001 | yizhong      |

|1002 | erzhong      |

|1003 | sanzhong      |

进来之后,再使用命令进行查询,如:

mysql> select * from school_index where id=1001;

|  id | name        |

|1001 | yizhong      |

使用命令查询 id 为1001的这条数据,如:

mysql> explain select * from school_index where id=1001;

+----+------------+-------+-----------+-----+--------------+---…

|  id | select_type | table | partitions | type | possible_keys | key…

|  1|SIMPLE  |school_index | NULL   |ref  |id        |id…

+----+------------+-------+-----------+-----+--------------+---…

打印信息中前面都是和之前一样的,但是 type 变为了 ref,而不是 ALL,代表它没有进行全表扫描;rows为1,扫描的行数变成了1;所以像这个 sql 语句的执行过程中,就执行了全表审核的功能。

3、like '%test%’,不使用索引

4、like 'test%',使用索引

5、是否运用索引(演示)

使用命令来演示是否运用索引,得出的结果为 type 是 ALL,rows 是3,没有运用索引,如:

mysql> explain select * from school_index where id like ’%1001%’;

+----+------------+-------+-----------+-----+--------------+---…

|  id | select_type | table | partitions | type | possible_keys | key…

|  1|SIMPLE  |school_index | NULL   |ALL  | NULL        | NU…

+----+------------+-------+-----------+-----+--------------+---…

再进行查看1001,得出的结果也都表示没有运用索引:

mysql> explain select * from school_index where id like ’1001%’;

+----+------------+-------+-----------+-----+--------------+---…

|  id | select_type | table | partitions | type | possible_keys | key…

|  1|SIMPLE  |school_index | NULL   |ALL  | NULL        | NU…

+----+------------+-------+-----------+-----+--------------+---…

mysql> explain select * from school_index where id like ’1001’;

+----+------------+-------+-----------+-----+--------------+---…

|  id | select_type | table | partitions | type | possible_keys | key…

|  1|SIMPLE  |school_index | NULL   |ALL  | NULL        | NU…

+----+------------+-------+-----------+-----+--------------+---…

注意:在使用时,一定要注意用法。如果这个 like 是整型的情况下,这里用的是1001,就没有运用索引,这就是关于 id 的用法。因为id是整型的,所以在用的时候要注意了,它只是会在按照 id=1001的方式做等值查询的时候运用索引,其他方式都不会运用索引。

在 name 上创建索引,现在表已经创建好了,还需要使用命令在 school_index 表中为 name 创建索引,如:

mysql> create index idx_name on school_index(name);

再执行 name 的查询,得出的结果说明运用了索引,如:

mysql> explain select * from school_index where name=’yizhon

g’;

+----+------------+-------+-----------+-----+--------------+---…

|  id | select_type | table | partitions | type | possible_keys | key…

|  1|SIMPLE  |school_index | NULL   |ref  | idx_name    | 23…

+----+------------+-------+-----------+-----+--------------+---…

再修改命令运行,得出的结果说明没有运用索引,如:

mysql> explain select * from school_index where name like '%yizhong%';

+----+------------+-------+-----------+-----+--------------+---…

|  id | select_type | table | partitions | type | possible_keys | key…

|  1|SIMPLE  |school_index | NULL   |ALL  | NULL       | NUL…

+----+------------+-------+-----------+-----+--------------+---…

但是把命令修改为 explain select * from school_index where name like 'yizhong%'; 运行,得出的结果说明运用了索引,如:

mysql> explain select * from school_index where name like 'yizhong%';

+----+------------+-------+-----------+-----+--------------+---…

|  id | select_type | table | partitions | type | possible_keys | key…

|  1|SIMPLE  |school_index | NULL |range  |idx_name    | 23…

+----+------------+-------+-----------+-----+--------------+---…

type 为 range, 是一个范围的索引,和前面的整型是不一样的,整型的 type 是ref,和 range 的等值是一样的,而这里是 range 并且是百分百的。

 

三、唯一索引

1、unique,不允许重复,可以为空值

比如在创建值的时候,使用 select * from school_index; 命令进行查询,得出的结果,可以看出没有设置主键,也没有设置唯一键,如:

mysql> select * from school_index;

id    name

1001 yizhong

1002 erzhong

1003 sanzhong

然后插入一条数据,再使用命令进行查询,得出的结果说明插入数据没问题,如:

mysql> insert into school_index values(1001,’sizhong’);

mysql> select * from school_index;

id     name

1001 yizhong

1002 erzhong

1003 sanzhong

1001 sizhong

紧接着进行查询 id=1001的数据,得出的结果为 type 是 ref,rows 是2;所以它运用了索引,会把数据扫描出来,而这是一个普通索引,没有任何限制,如:

mysql> explain select * from school_index where id=1001;

+----+------------+-------+-----------+-----+--------------+---…

|  id | select_type | table | partitions | type | possible_keys | key…

|  1|SIMPLE  |school_index | NULL   |ref  |id            | id

+----+------------+-------+-----------+-----+--------------+---…

而现在在这个表中进行打印表,如:

mysql> show create table school;

可以发现没有 index 这个表,所以可以去创建一个有唯一索引的表,再使用命令打印表,打印信息为 Key_name 为 idx_idColumn_name 为 id,可以看到已经有一个索引了,这就是唯一索引,如:

mysql> create unique index idx_id on school(id);

mysql> show indexes from school;

|  Table    | Non_unique | Key_name | Seq…  | Sub part…

| school    |           0 | idx_id    |      1… |    NULL…

然后查询表中的数据,再进行插入数据,就会提示报错,如:

mysql> select * from school;

mysql> insert into school values(1001,’sizhong’);

(ERROR 1062 (23000):Duplicate entry '1001' for key 'idx_id')

因为这里的 'idx_id' 是前面创建的唯一索引,那么这个唯一索引是不能给它赋重复的值,必须给它赋不同的值,创建唯一索引时,一定要注意字段的值是不是唯一的。

对于查看是否运用了索引可以再次执行查询1001数据命令,如:

mysql> explain select * from school where id=1001;

+----+------------+-------+-----------+-----+--------------+---…

|  id | select_type | table | partitions | type | possible_keys | key…

|  1|SIMPLE   |  school   | NULL   |const |idx_id        | idx…

+----+------------+-------+-----------+-----+--------------+---…

如上得出的结果为 type 值为 const,并且这里 rows 是1(扫描的是一行),可以看出运用了索引,因为这里使用的是唯一索引,与之前的普通索引的 type 是不一样的;因为在这里面它扫描出一行就不用再扫描了,这里本来就是唯一的,只有一条数据,所以唯一索引的效率更高。

2、可以对多个字段设置成唯一性索引

也可以创建多个字段去指定也行,比如把 email 和 username 作为一个唯一索引。先进行删除索引,再使用命令创建一个唯一索引。这个时候再来查看 school 表,如:

mysql> drop index idx_id on school;

mysql> create unique index idx_id_name on school(id,name);

mysql> show index from school;

|  Table    | Non_unique | Key_name | Seq…  | Sub part…

| school    |           0 | idx_id_name |      1… |    NULL…

| school    |           0 | idx_id_name |      2… |    NULL…

从上面查询结果可以看到它创建了类似于两个字段的索引,其实它不是两个索引,这里的 Key_name 都是一样的,并且指定的一个是1,一个是2;Column_name 是id 和 name。这就是唯一索引的概念。就是可以通过多列设置这样的唯一索引。

在使用唯一索引时会遇到的问题:在做查询的时候,是否任何一个字段作为查询条件,都可以走索引,如:

mysql> explain select * from school where id=1001;

+----+------------+-------+-----------+-----+--------------+---…

|  id | select_type | table | partitions | type | possible_keys | key…

|  1|SIMPLE   |  school   | NULL   |ref  |idx_id_name| idx_id…

+----+------------+-------+-----------+-----+--------------+---…

运行如上得出的结果显示是走了索引的。

再分别使用 like 命令进行查询,如:

mysql>explain select * from school where name like '%yizhong%';

+----+------------+-------+-----------+-----+--------------+---…

|  id | select_type | table | partitions | type | possibl… | rows…

|  1|SIMPLE  |  school   | NULL   |index |NULL …   | 3…

+----+------------+-------+-----------+-----+--------------+---…

mysql> explain select * from school where name like 'yizhong%';

+----+------------+-------+-----------+-----+--------------+---…

|  id | select_type | table | partitions | type | possibl… | rows…

|  1|SIMPLE  |  school   | NULL   |index |NULL …   | 3…

+----+------------+-------+-----------+-----+--------------+---…

mysql> explain select * from school where name= 'yizhong';

+----+------------+-------+-----------+-----+--------------+---…

|  id | select_type | table | partitions | type | possibl… | rows…

|  1|SIMPLE  |  school   | NULL   |index |NULL …   | 3…

+----+------------+-------+-----------+-----+--------------+---…

如上命令做的等值查询,但得出的结果显示都是扫描了三行,都没有走索引。但实际上 name 字段是加了索引的,所以这就反映了一个侧面的问题,在创建唯一索引的并涉及到多个列时,它只会以最左边的这一列作为索引的条件。

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

推荐镜像

更多