当前位置: 首页 > news >正文

MySQL的索引(索引的创建和设计原则):

目录

索引的创建:

索引的概念和创建和查看以及删除语法格式:

普通索引:

创建索引:

查看索引:

删除索引:

唯一性索引:

创建索引:

查看索引:

删除索引:

主键索引:

创建索引:

查看索引:

删除索引:

单列索引:

创建索引:

查看索引:

删除索引:

多列索引:

创建索引:

查看索引:

删除索引:

隐藏索引:

创建隐藏索引:

修改索引的可见性:

索引的设计原则:

适合创建索引的情况:

字段的数值有唯一性的限制:

频繁作为where查询条件的字段:

经常group by和order by的字段:

update、delete的where条件:

distinct字段需要创建索引:

多表join连接操作时:

适用类型小的创建索引:

使用字符串前缀创建索引:

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

使用最频繁的列放到联合索引的左侧:

多个字段都要创建索引的情况下,联合索引优于单列索引

索引的数目:

不适合创建索引的情况:

数据量小的表不创建索引:

有大量重复数据的列不创建索引:

避免对经常更新的表创建过多的索引:

不建议用无序的值作为索引:

删除不再使用或者很少的索引:

不要定义冗余或者重复的索引:


MySQL的索引包括主键索引、唯一性索引、普通索引、单列索引、多列索引、全文索引和空间索引。

主要对主键索引、唯一性索引、普通索引、单列索引、多列索引进行讲解。

索引的创建:

MySQL支持在单个列或者多个列上创建索引,在创建表时使用create table中指定索引列,或者使用alter table语句在已有的表上创建索引,再或者使用create index语句在已有表上添加索引。

create table 表名(字段名 数据类型 约束,...
);
create table 表名[字段名 数据类型]
[UNIQUE|FULLTEXT|SPATIAL] [INDEX|KEY] [索引名](字段名[索引长度]
)[ASC|DESC];INDE

UNIQUE、FULLTEXT和SPATIAL:分别表示唯一索引、全文索引和空间索引。

INDEX和KEY:作用相同,指定创建索引。

如果未指定索引名,那么默认索引名为字段名。

索引长度只有字符串类型才能指定索引长度。

ASC、DESC:指定升序或者降序的索引值存储。

索引的概念和创建和查看以及删除语法格式:

普通索引:

在创建普通索引时,不附加任何限制条件,只是用于提高查询效率。可以创建在任何数据类型中,其值是否唯一和非空,由字段本身的完整性约束条件决定。建立索引之后,可以通过索引进行查询。

创建索引:

create table 表名(字段名 数据类型,...INDEX 索引名(字段名)
);
alter table 表名
add index 索引名(字段名);
create index 索引名 on 表名(字段名);

查看索引:

show create table 表名;
或者
show index from 表名;

删除索引:

alter table 表名 drop index 索引名;
drop index 索引名 on 表名;

唯一性索引:

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

创建索引:

create table 表名(字段名 数据类型,...UNIQUE INDEX 索引名(字段名)
);
alter table 表名
add unique 索引名(字段名);
create unique index 索引名 on 表名(字段名);

查看索引:

show create table 表名;
或者
show index from 表名;

删除索引:

alter table 表名 drop index 索引名;
drop index 索引名 on 表名;

添加了auto_increment约束字段的唯一索引不能被删除。

主键索引:

是一种特殊的唯一性索引,在唯一索引的基础上增加了不为空的约束,一张表中只能有一个主键索引。

创建索引:

create table 表名(字段名 数据类型 PRIMARY KEY [AUTO_INCREMENT],...
);

查看索引:

show create table 表名;
或者
show index from 表名;

删除索引:

alter table 表名 drop index 索引名;
drop index 索引名 on 表名;

添加了auto_increment约束字段的唯一索引不能被删除。

单列索引:

在表中的单个字段上创建索引。一张表可以有多个单列索引。

以唯一索引做演示:

创建索引:

create table 表名(字段名 数据类型,...UNIQUE INDEX 索引名(字段名);
);
alter table 表名
add unique 索引名(字段名);
create unique index 索引名 on 表名(字段名);

查看索引:

show create table 表名;
或者
show index from 表名;

删除索引:

alter table 表名 drop index 索引名;
drop index 索引名 on 表名;

多列索引:

在表的多个字段上创建一个索引。使用组合索引时遵循最左前缀集合。

以普通索引演示:

创建索引:

create table 表名(字段名 数据类型,...INDEX 索引名(字段名1,字段名2,...)
);
alter table 表名
add index 索引名(字段名1,...);
create index 索引名 on 表名(字段名1,...);

查看索引:

show create table 表名;
或者
show index from 表名;

删除索引:

alter table 表名 drop index 索引名;
alter table 表名 drop index 索引名;

隐藏索引:

MySQL8.0开始支持隐藏索引,将待删除的索引设置为隐藏索引,使查询优化器不再使用这个索引,如果设置为隐藏索引后系统不受任何影响,就可以删除索引。可以避免显式删除之后出现错误重新创建索引时消耗过多的资源。

逐渐不能设置为隐藏索引,如果没有主键,第一个唯一非空索引会成为隐式主键,也不能设置为隐藏索引。

索引默认是可见的,可以通过visible和invisible关键词设置索引的可见性。

创建隐藏索引:

create table 表名(字段名 数据类型,index 索引名(字段名) invisible
);
alter table 表名
add index 索引名(字段名) invisible;
create index 索引名 on 表名(字段名) invisible;

修改索引的可见性:

alter table 表名
alter index 索引名 invisible;可见改为不可见
alter table 表名
alter index 索引名 visible;不可见改为可见

当索引被隐藏时,内容仍然适合正常索引一样实时更新的。

索引的设计原则:

适合创建索引的情况:

字段的数值有唯一性的限制:

索引本身可以起到约束的作用,因此在数据表中,如果某个字段是唯一性的,可以直接创建唯一性索引或者主键索引,能够更好地通过该索引确定某条记录。

频繁作为where查询条件的字段:

在数据量大的情况下,创建普通索引就可以大幅度提升数据查询的效率。

经常group by和order by的字段:

索引就是让数据按照某种顺序进行存储或者检索,如果使用group by或者order by就需要对分组或者排序的字段进行索引。

对于group by和order by一起进行时,可以分别对相应的列创建索引,也可以使用联合索引。一般使用联合索引,将group by后的字段写在联合索引前面,order by后的字段写在联合索引后面,这样相较于效率更高。

update、delete的where条件:

对数据按照某个条件进行查询后再进行update或者delete,对where字段创建索引,能够大幅提升效率。因为需要先根据where条件列检索出来的记录,然后进行更新或者删除,如果进行更新时,更新的字段是非索引字段,提升的效率会更明显,因为非索引字段更新不需要对索引进行维护。

distinct字段需要创建索引:

需要对某个字段进行去重时,可以对这个字段创建索引,能够提升查询效率。

多表join连接操作时:

连接表的数量尽量不超过3张,因为增加一张表相当于嵌套了一层循环,严重影响查询的效率。对where条件创建索引。对用于连接的字段创建索引,并且该字段在多张表中的类型一致。

适用类型小的创建索引:

想对某个列创建索引,尽量让索引使用较小的类型。因为数据类型越小,查询时进行得比较操作越快,索引占用的存储空间也会更少,一个数据也就能存储更多记录,进而可以减少磁盘I/O带来的性能损耗。

对于主键更加适用,因为不仅聚簇索引中会存储主键值,非聚簇索引的节点都会存储一份记录的主键值,如果主键值的类型越小,就能节省更多的存储空间和更高效的I/O。

使用字符串前缀创建索引:

B+树索引中的记录需要把该列的完整字符串存储起来,字符串越长的话,索引中占用的存储空间越大,还更费时。

B+树种索引中索引列存储的字符串很长,会导致在比较时消耗的时间更多。

通过截取字段前面的一部分内容建立索引,也就是前缀索引。虽然不能精确的定位,但能定位到相应的前缀所在的位置,然后根据前缀相同的记录的主键值回表查询到完整的字符串。前缀索引节约了空间又减少了字符串的比较时间,还大体能解决排序的问题。

根据区分度来选择索引的长度。

区分度:

count(distinct left(字段名,索引长度))/count(*)

使用前缀索引之后无法支持索引排序,只能使用文件排序。

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

列的基数是指某一列中不重复的数据的个数。在记录行数一定的情况下,列的基数越大,该列中的值越分散,相反列的基数越小,该列中的值越集中。

区分度:

count(distinct 字段名)/count(*)

区分度越接近1越好。

在联合索引中,把区分度高的列放在前面。

使用最频繁的列放到联合索引的左侧:

这样可以相对创建较少的索引。由于“最左前缀原则”,可以增加联合索引的使用率。

多个字段都要创建索引的情况下,联合索引优于单列索引

索引的数目:

索引不是越多越好,需要限制每张表上的索引数,一般不超过6个。

因为每个索引都需要占用磁盘,索引越多,需要的磁盘空间就越大。

索引会影响增删改操作的效率,因为要进行维护索引,造成性能消耗。

优化器在选择时,会对每一个可以用到的索引进行评估,所以同时有很多个索引都能用于查询,会增加优化器生成执行计划,导致查询性能降低。

不适合创建索引的情况:

where中使用不到的字段,不设置索引:

因为起不到快速定位的字段不需要创建索引。

数据量小的表不创建索引:

因为数据量小的话,查询花费的时间与是否创建索引并没太大关系。

有大量重复数据的列不创建索引:

重复的数据太多,如果创建索引,无法快速的进行定位,会降低数据更新的速度。

避免对经常更新的表创建过多的索引:

频繁更新的字段不一定要创建索引,因为更新数据时,索引也会更新,造成性能损耗。

经常更新的表创建过多的索引,更新时会大大降低更新表的速度。

不建议用无序的值作为索引:

当使用无序的列作为索引时,B+树索引时一个有序的,会按照主键的大小进行排序,可能会导致页分裂,数据的转移。

删除不再使用或者很少的索引:

能够减少索引对更新操作的影响。

不要定义冗余或者重复的索引:

对同一个列创建了多个索引,会导致只使用该列的一个索引,而其他的索引就是冗余的索引,不仅增加了存储空间的浪费,还会增加维护的成本。

对同一个列创建了重复的索引,如主键值创建了唯一索引,还定义了普通索引,主键值本身就会生成聚簇索引,唯一索引和普通索引就是重复的。

http://www.xdnf.cn/news/1296307.html

相关文章:

  • 并发编程 - 读写锁(ReentrantReadWriteLock)的探究
  • JVM的逃逸分析深入学习
  • T05_卷积神经网络
  • 消费级显卡分布式智能体协同:构建高性价比医疗AI互动智能体的理论与实践路径
  • TypeScript 中,! 是 非空断言操作符
  • 上网行为安全概述和组网方案
  • EN 61010电子电气设备安全要求标准
  • 抗辐照CANFD通信芯片在高安全领域国产化替代的研究
  • 从根源到生态:Apache Doris 与 StarRocks 的深度对比 —— 论开源基因与长期价值的优越性
  • Gemma 3 多模态推理 通过vllm运行Gemma-3-27B-IT模型的推理服务
  • NineData云原生智能数据管理平台新功能发布|2025年7月版
  • 基于U-NET遥感影像语义分割任务快速上手
  • git upstream
  • 流式数据服务端怎么传给前端,前端怎么接收?
  • 入门概述(面试常问)
  • vercel部署上线
  • 【数据分享】351个地级市农业相关数据(2013-2022)-有缺失值
  • 数智先锋 | 告别运维黑盒!豪鹏科技×Bonree ONE构建全栈智能可观测体系
  • 带环链表详解:环形链表检测与入环节点查找
  • 从 Notion 的水土不服到 Codes 的本土突围:研发管理工具的适性之道​
  • Linux下的软件编程——framebuffer(文件操作的应用)
  • 表达式树实战:Unity动态逻辑编程
  • tp5集成elasticsearch笔记
  • Unity中的神经网络遗传算法实战
  • 一篇文章读懂.Net的依赖注入
  • .NET 的 WebApi 项目必要可配置项都有哪些?
  • .Net4.0 WPF中实现下拉框搜索效果
  • 面试题之项目中git如何进行管理
  • 如何启动本机mysql数据库
  • 在mysql> 下怎么运行 .sql脚本