MYSQL10_索引的分类、创建修改删除索引、新特性降序隐藏、适合以及不适合使用索引情况

文章目录

  • [①. 索引的分类 - 功能、物理、个数](#①. 索引的分类 - 功能、物理、个数)
  • [②. 各个索引介绍 - 普通、唯一等](#②. 各个索引介绍 - 普通、唯一等)
  • [③. 创建表时创建索引](#③. 创建表时创建索引)
  • [④. 使用ALTER创建索引](#④. 使用ALTER创建索引)
  • [⑤. 使用CREATE INDEX](#⑤. 使用CREATE INDEX)
  • [⑥. 删除索引 - index](#⑥. 删除索引 - index)
  • [⑦. MySQL8.0索引新特性 - 降序索引](#⑦. MySQL8.0索引新特性 - 降序索引)
  • [⑧. MySQL8.0索引新特性 - 隐藏索引](#⑧. MySQL8.0索引新特性 - 隐藏索引)
  • [⑨. 哪些情况适合用索引](#⑨. 哪些情况适合用索引)
  • [⑩. 哪些情况不适合创建索引](#⑩. 哪些情况不适合创建索引)
  • [⑩①. 限制索引的数目](#⑩①. 限制索引的数目)

①. 索引的分类 - 功能、物理、个数

  • ①. 从功能逻辑上说,索引主要有4种,分别是普通索引、唯一索引、主键索引、全文索引

  • ②. 按照物理实现方式,索引可以分为2种:聚簇索引和非聚簇索引

  • ③. 按照作用字段个数进行划分,分成单列索引和联合索引

②. 各个索引介绍 - 普通、唯一等

  • ①. 普通索引
    在创建普通索引时,不附加任何限制条件,只是用于提高查询效率。这类索引可以创建在任何数据类型中,其值是否唯一和非空,要由字段本身的完整性约束条件决定。建立索引以后,可以通过索引进行查询。例如,在表student的字段name上建立一个普通索引,查询记录时就可以根据该索引进行查询

  • ②. 唯一性索引
    使用UNIQUE参数可以设置索引为唯一性索引,在创建唯一性索引时,限制该索引的值必须是唯一的,但允许空值。在一张数据表里可以有多个唯一索引

  • ③. 主键索引
    主键索引就是一种特殊的唯一性索引,在唯一索引的基础上增加了不为空的约束,也就是NOT NULL+UNIQUE,一张表里最多只有一个主键索引

  • ④. 单列索引
    在表中的单个字段上创建索引。单列索引只根据该字段进行索引。单列索引可以是普通索引,也可以是唯一性索引,还可以是全文索引。只要保证该索引只对应一个字段即可。一个表可以有多个单列索引

  • ⑤. 多列索引
    多列索引是在表的多个字段组合上创建一个索引。该索引指向创建时对应的多个字段,可以通过这几个字段进行查询,但是只有查询条件中使用了这些字段中的第一个字段时才会被使用。例如,在表中的字段id、name和gender上建立一个多列索引idx_id_name_gender,只有在查询条件中使用了字段id时该索引才会被使用。使用组合索引时遵循最左前缀集合

  • ⑥. 全文索引

  1. 全文索引也称全文检索是目前搜索引擎使用的一种关键技术。它能够利用【分词技术】等多种算法智能分析出文本文字中关键词的频率和重要性,然后按照一定的算法规则智能地筛选出我们想要的搜索结果。全文索引非常适合大型数据集,对于小的数据集,它的用处比较小(目前可用es替代)
  2. 使用参数FULLTEXT可以设置全文索引
  • ⑦. 空间索引
    使用参数SPATIAL可以设置索引为空间索引。空间索引只能建立在空间数据类型上,这样可以提高系统获取空间数据的效率。MySQL中的空间数据类型包括GEOMETRY、POINT、LINESTRING和POLYGON等。目前只有MyISAM存储引擎支持空间检索,而且索引的字段不能为空值。对于初学者来说,这类索引很少会用到

③. 创建表时创建索引

  • ①. 创建表时创建索引 - 语法
  1. UNIQUE、FULLTEXT和SPATIAL为可选参数,分别表示唯一索引、全文索引和空间索引
  2. INDEX与KEY为同义词,两者的作用相同,用来指定创建索引
  3. index_name指定索引的名称,为可选参数,如果不指定,那么MysQL默认col_name为索引名
  4. col_name为需要创建索引的字段列,该列必须从数据表中定义的多个列中选择
  5. length为可选参数,表示索引的长度,只有字符串类型的字段才能指定索引长度;
  6. ASC或DESC指定升序或者降序的索引值存储。
sql 复制代码
#语法
create table table_name [col_name data_type]
[UNIQUE | FULLTEXT |SPATIAL] [INDEX | KEY] [index_name](col_name[length][ASC | DESC])
  • ②. 示例如下:
sql 复制代码
CREATE TABLE book (
	`book_id` INT,
	book_name VARCHAR ( 100 ),
	email varchar(20) ,
	AUTHORS VARCHAR ( 100 ),
	info VARCHAR ( 100 ),
	#声明索引
	PRIMARY KEY(`book_id`),
	INDEX idx_bname ( book_name ),
	UNIQUE INDEX u_idx_email(`email`)
);
  • ③. 通过命令查看索引
sql 复制代码
#方式一
SHOW CREATE TABLE book;
#方式二
SHOW INDEX FROM book;
#性能分析工具
EXPLAIN SELECT * FROM book WHERE book_name = 'mqsql';

④. 使用ALTER创建索引

  • ①. ALTER TABLE语法创建如下
sql 复制代码
ALTER TABLE table_name ADD [UNIQUE | FULLTEXT | SPATIAL] [INDEX | KEY]
[index_name] (col_name[length],...) [ASC | DESC]
  • ②. 案例演示
sql 复制代码
CREATE TABLE book5(
book_id INT ,
book_name VARCHAR(100),
AUTHORS VARCHAR(100),
info VARCHAR(100) ,
COMMENT VARCHAR(100),
year_publication YEAR
);

SHOW INDEX FROM book5;
ALTER TABLE book5 ADD INDEX idx_cmt(COMMENT);
ALTER TABLE book5 ADD UNIQUE uk_idx_bname(book_name);
ALTER TABLE book5 ADD INDEX mul_bid_bname_info(book_id,book_name,info);

⑤. 使用CREATE INDEX

  • ①. CREATE INDEX基本语法如下
sql 复制代码
CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX index_name
ON table_name (col_name[length],...) [ASC | DESC]
  • ②. 案例演示
sql 复制代码
CREATE TABLE book6(
book_id INT ,
book_name VARCHAR(100),
AUTHORS VARCHAR(100),
info VARCHAR(100) ,
COMMENT VARCHAR(100),
year_publication YEAR
);

SHOW INDEX FROM book6;
CREATE INDEX idx_cmt ON book6(COMMENT);
CREATE UNIQUE INDEX  uk_idx_bname ON book6(book_name);
CREATE INDEX mul_bid_bname_info ON book6(book_id,book_name,info);

⑥. 删除索引 - index

  • ①. ALTER TABLE删除索引的基本语法格式如下
sql 复制代码
ALTER TABLE table_name DROP INDEX index_name;
  • ②. 使用DROP INDEX语句删除索引的基本语法格式如下
sql 复制代码
DROP INDEX index_name ON table_name;
  • ③. 提示:删除表中的列时,如果要删除的列为索引的组成部分,则该列也会从索引中删除。如果组成索引的所有列都被删除,则整个索引将被删除

⑦. MySQL8.0索引新特性 - 降序索引

  • ①. 分别在MySQL 5.7版本和MySQL 8.0版本中创建数据表ts1,结果如下
sql 复制代码
CREATE TABLE ts1(a int,b int,index idx_a_b(a,b desc));
  • ②. 在MySQL 5.7版本中查看数据表ts1的执行计划,结果如下
  1. 从结果可以看出,执行计划中扫描数为799,而且使用了Using filesort
  2. 提示 Using filesort是MySQL中一种速度比较慢的外部排序,能避免是最好的。多数情况下,管理员可以通过优化索引来尽量避免出现Using filesort,从而提高数据库执行速度
sql 复制代码
EXPLAIN SELECT * FROM ts1 ORDER BY a,b DESC LIMIT 5
  • ③. 在MySQL 8.0版本中查看数据表ts1的执行计划。从结果可以看出,执行计划中扫描数为5,而且没有使用Using filesort

  • ④. 注意:降序索引只对查询中特定的排序顺序有效,如果使用不当,反而查询效率更低。例如,上述查询排序条件改为order by a desc, b desc,MySQL 5.7的执行计划要明显好于MySQL 8.0

sql 复制代码
EXPLAIN SELECT * FROM ts1 ORDER BY a DESC,b DESC LIMIT 5;

⑧. MySQL8.0索引新特性 - 隐藏索引

  • ①. 在MySQL 5.7版本及之前,只能通过显式的方式删除索引。此时,如果发现删除索引后出现错误,又只能通过显式创建索引的方式将删除的索引创建回来。如果数据表中的数据量非常大,或者数据表本身比较大,这种操作就会消耗系统过多的资源,操作成本非常高

  • ②. 从MySQL 8.x开始支持 隐藏索引invisible indexes,只需要将待删除的索引设置为隐藏索引,使查询优化器不再使用这个索引即使使用force index强制使用索引,优化器也不会使用该索引,确认将索引设置为隐藏索引后系统不受任何响应,就可以彻底删除索引。 这种通过先将索引设置为隐藏索引,再删除索引的方式就是软删除

  • ③. 创建表时直接创建

sql 复制代码
CREATE TABLE tablename(
propname1 type1[CONSTRAINT1],
propname2 type2[CONSTRAINT2],
......
propnamen typen,
INDEX [indexname](propname1 [(length)]) INVISIBLE
);
  • ④. 在已经存在的表上创建
sql 复制代码
CREATE INDEX indexname
ON tablename(propname[(length)]) INVISIBLE;
  • ⑤. 通过ALTER TABLE语句创建
sql 复制代码
ALTER TABLE tablename
ADD INDEX indexname (propname [(length)]) INVISIBLE;
  • ⑥. 切换索引可见状态 已存在的索引可通过如下语句切换可见状态:
sql 复制代码
ALTER TABLE tablename ALTER INDEX index_name INVISIBLE; #切换成隐藏索引
ALTER TABLE tablename ALTER INDEX index_name VISIBLE; #切换成非隐藏索引

⑨. 哪些情况适合用索引

  • ①. 字段的数值有唯一性的限制
    唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。例如,学生表中学号是具有唯一性的字段。为该字段建立唯一性索引可以很快的确定某个学生的信息。如果使用姓名的话,可能存在同名现象,从而降低查询速度

  • ②. 频繁作为WHERE查询条件的字段

  • ③. 经常GROUP BY和ORDER BY的列

  • ④. UPDATE、DELETE的WHERE条件列

  • ⑤. DISTINCT字段需要创建索引

  • ⑥. 多表JOIN连接操作时,创建索引注意事项

  1. 连接表的数量尽量不超过3张,因为每增加一张表相当于增加了一次嵌套的循环,数量级增长会非常快,严重影响查询的效率
  2. 对Where条件创建索引
  3. 对用于连接的字段创建索引,并且该字段在多张表中的类型必须一致
  • ⑦. 使用列的类型小的创建索引
  1. 数据类型越小,在查询进行的比较操作进行越快
  2. 数据类型越小,索引占用的存储空间越小,在一个数据页内就可以放下更多的记录,从而减少磁盘的I/O带来的性能损耗,也就意味着可以把更多的数据页缓存到内存,从而加快读写性能
  • ⑧. 使用字符串前缀创建索引
    如果索引字段的值很长,最好使用值的前缀来索引。例如,TEXT和BLOG类型的字段,进行全文检索会很浪费时间。如果只检索字段的前面的若干个字符,这样可以提高检索速度

  • ⑨. 区分度高(散列性高)的列适合作为索引

  • ⑩. 使用最频繁的列放到联合索引的左侧

⑩. 哪些情况不适合创建索引

  • ①. 在where中使用不到的字段,不要设置索引

  • ②. 数据量小的表最好不要使用索引(少于1000没必要创建索引),索引会占用空间,维护也需要成本

  • ③. 有大量重复数据的列上不要建立索引

  • ④. 避免对经常更新的表创建过多的索引

  • ⑤. 不建议用无序的值作为索引(例如身份证号码、UUID)

  • ⑥. 删除不再使用或者很少使用的索引

  • ⑦. 不要定义冗余或重复的索引

⑩①. 限制索引的数目

在实际工作中,我们也需要注意平衡,索引的数目不是越多越好。我们需要限制每张表上索引数量,建议单张表索引数量不超过6个,原因如下

  • ①. 每个索引都需要占用磁盘空间,索引越多,需要的磁盘空间就越大

  • ②. 索引会影响INSERT DELETE UPDATE等语句的性能,因为表中的数据更改的同时,索引也会进行调整和更新,会造成负担

  • ③. 优化器在选择如何优化查询时,会根据统一信息,对每一个可以用到的索引来进行评估,以生成出一个最好的执行计划,如果同时有很多索引都可以用于查询,会增加MYSQL优化器生成执行计划时间,降低查询性能

相关推荐
这周也會开心几秒前
云服务器安装JDK、Tomcat、MySQL
java·服务器·tomcat
hrrrrb1 小时前
【Spring Security】Spring Security 概念
java·数据库·spring
小信丶1 小时前
Spring 中解决 “Could not autowire. There is more than one bean of type“ 错误
java·spring
sdgsdgdsgc1 小时前
Next.js企业级应用开发:SSR、ISR与性能监控方案
开发语言·前端·javascript
心止水j1 小时前
spark
javascript·数据库·spark
周杰伦_Jay2 小时前
【Java虚拟机(JVM)全面解析】从原理到面试实战、JVM故障处理、类加载、内存区域、垃圾回收
java·jvm
xujiangyan_2 小时前
Redis详解
数据库·redis·缓存
rit84324995 小时前
基于MATLAB的模糊图像复原
开发语言·matlab
fie88895 小时前
基于MATLAB的声呐图像特征提取与显示
开发语言·人工智能
Y编程小白5 小时前
PostgreSQL在Linux中的部署和安装教程
数据库·postgresql