MySql索引详解-各种索引的定义与区别和应用

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 什么是索引?索引的作用,有无索引的区别。

什么是索引?索引的作用,有无索引的区别。


一、索引基础:增删改查



以下场景既适用于单值索引也适用于复合索引


1.新增索引的几种方式


只有主键索引不适用create index 其他均是适用的。

-- 方式一:
create index idx_building_id on tb_mdm_unit(building_id) using btree comment '楼栋id';
-- 方式二:
alter table tb_mdm_unit add index idx_building_id(building_id) using btree comment '楼栋id';
-- 方式三:这里也可以在声明列时直接声明
drop table if exists testTable;
create table testTable(
id tinyint  comment 'id',
column1 tinyint not null comment '列1',
column2 BIGINT not null comment '列2',
column3 MEDIUMINT not null comment '列3',
column4 DATETIME not null comment '列4',
column5 date not null comment '列5',
column6 TIMESTAMP not null comment '列6',
column7 year not null comment '列7',
column8 GEOMETRY not null comment '列8',
column9 varchar(20)  not null comment '列9',
-- PRIMARY key(id) using BTREE comment '主键',
PRIMARY key(id,column1) using BTREE comment '复合主键',
UNIQUE key colu1_idx(column1) using BTREE comment '唯一索引',
UNIQUE key colu1_cdx(column1,column2) using BTREE comment '复合唯一索引',
index colu3_idx(column3) using BTREE comment '普通索引1',
index dolu3_cdx(column3,column4) using BTREE comment '复合普通索引1',
fulltext colu9_idx(column9) comment '全文索引',
SPATIAL index colu8_idx(column8) comment '空间索引'
);


2.删除索引的几种方式


drop index 这种删除方式不适用于主键索引,其他索引均可适用。

drop index idx_building_id on tb_mdm_unit;
alter table tb_mdm_unit drop index idx_building_id;


3.修改索引的几种方式


下面的修改只有在mysql8中才可以使用,是用来将索引标识未可见不可见的(查看可见不可见可以使用show index from table)。索引不可见以后,条件使用索引字段将不走索引。如果是想将单列索引修改成复合索引,这种只能是删了重建才可以。

-- 修改索引可见(mysql8.0以后支持)
alter table tb_mdm_unit alter index idx_building_id visible;
-- 修改索引不可见(mysql8.0以后支持)
alter table tb_mdm_unit alter index idx_building_id invisible;


4.查询索引的几种方式


-- 方式一:查看建表语句,此时可以看到
show create table tb_mdm_floor;
-- 方式二:查看表的所有索引
show index from tb_mdm_floor;
-- 方式三:查看所有列(会标明列上的索引)
show columns from tb_mdm_floor;


二、索引的分类



从功能上对索引进行划分的话,可以划分为以下几种索引。


1.主键索引


非null且唯一,可以为将任意字段类型设置为主键,不过对于blob/text添加主键时必须指明主键长度(其实就是前缀索引),因为blob存储的是二进制文件,text存储的是文本,都比较长,如果使用原始信息做主键,会导致主键过长,从而影响查询效率,下面是测试使用各个字段做主键的sql。


主键使用切记不要更新主键,更新会导致BTree的重新计算主键索引位置,很耗时。一般不应该操作主键的更新。

下面是验证各种数据类型是否可以作为主键的sql

drop table if exists testTable;
create table testTable(
id integer comment '主键',
column1 tinyint not null comment '列1',
column2 BIGINT not null comment '列2',
column3 MEDIUMINT not null comment '列3',
column4 DATETIME not null comment '列4',
column5 date not null comment '列5',
column6 TIMESTAMP not null comment '列6',
column7 year not null comment '列7',
column8 char not null comment '列8',
column9 varchar(20)  not null comment '列9',
column10 blob not null comment '列11',
column11 text not null comment '列12',
column12 enum('one','two','three') not null comment '列13',
column13 set('one','two')  comment '列14'
);
alter table testTable add primary key(id) comment '测试主键'; alter table testTable drop PRIMARY key ;
alter table testTable add primary key(column1) comment '测试主键';alter table testTable drop PRIMARY key ;
alter table testTable add primary key(column2) comment '测试主键';alter table testTable drop PRIMARY key ;
alter table testTable add primary key(column3) comment '测试主键';alter table testTable drop PRIMARY key ;
alter table testTable add primary key(column4) comment '测试主键';alter table testTable drop PRIMARY key ;
alter table testTable add primary key(column5) comment '测试主键';alter table testTable drop PRIMARY key ;
alter table testTable add primary key(column6) comment '测试主键';alter table testTable drop PRIMARY key ;
alter table testTable add primary key(column7) comment '测试主键';alter table testTable drop PRIMARY key ;
alter table testTable add primary key(column8) comment '测试主键';alter table testTable drop PRIMARY key ;
alter table testTable add primary key(column9) comment '测试主键';alter table testTable drop PRIMARY key ;
alter table testTable add primary key(column10(10)) comment '测试主键';alter table testTable drop PRIMARY key ; -- blob 只能添加前缀索引类型的主键
alter table testTable add primary key(column11(10)) comment '测试主键';alter table testTable drop PRIMARY key ; -- text 只能添加前缀索引类型的主键
alter table testTable add primary key(column12) comment '测试主键';alter table testTable drop PRIMARY key ;
alter table testTable add primary key(column13) comment '测试主键';alter table testTable drop PRIMARY key ;


主键的新增

-- 方式一:修改表添加
alter table testTable add primary key(column13) comment '测试主键';
-- 方式二:建表字段上指定
drop table if exists testTable;
create table testTable(
id tinyint PRIMARY key auto_increment comment '测试主键'
);
-- 方式三: 建表末尾指定
drop table if exists testTable;
create table testTable(
id tinyint  comment 'id',
PRIMARY key(id) using BTREE comment '测试主键'
);


删除主键

alter table testTable drop PRIMARY key ;


主键的查看,使用索引的通用查看方法即可(第一节中)。此外主键可以是复合索引,主键也可以是前缀索引。如下举例:

alter table testTable add PRIMARY key(id,column1) using btree comment '复合主键索引';
alter table testTable add PRIMARY key(column9(10)) using btree comment '前缀主键索引';


2.唯一索引


非null,可以使用在任何类型的字段上。没有特别要求,都可以使用,可以建立复合唯一索引,前缀唯一索引(这个使用需要慎重),其他的和主键索引的创建删除都没有任何的区别,这里就不重复列举了。


3.普通索引


对字段类型没有要求,可以创建在任何数据类型上,用以提升查询效率。普通索引同样可以是复合索引,也可以是前缀索引,使用上便是第一节的列举情况。


4.复合索引


其实就是普通索引的变种,支持多列共同构建一个索引。使用参考第一节,这里不重复列举了。


5.全文索引


全文索引功能类似于ES,可以根据关键字进行快速查找,在不使用全文索引的情况下,模糊匹配查询like ‘%张三’,这种会导致索引失效。因此mysql也是在引入了全文索引fulltext,用以支持模糊查询的快速查找,全文索引和模糊查询的效率不是一个量级的。==在MySql5.6以前只有MYISAM支持fulltext,在5.6及以后INNODB和MYISAM均支持全文索引了,且全文索引只能建立在字符串类型上,如char、varchar、text等数据类型。==这里介绍全文索引的基础用法,不深入探讨。


全文索引的新增:

-- 方式一:建表时添加全文索引
drop table if exists testTable;
create table testTable(
id tinyint  comment 'id',
column1 tinyint not null comment '列1',
column8 text not null  comment '经纬度列',
column9 varchar(50) not null comment '列9',
fulltext index colu9_idx(column9) comment '全文索引',
fulltext index colu8_idx(column8,column9) comment '复合全文索引'
);
-- 方式二:使用create index 添加
create fulltext index colu9_fullindex on testTable(column9) comment '全文索引';
-- 方式三:使用alter table 添加
alter table testTable add fulltext index colu8_idx(column8,column9) comment '复合全文索引';


全文索引的删除查看和普通索引没有任何区别,这里不重复说了,来看下全文索引的使用吧:

MATCH (col1,col2,...) AGAINST (expr [search_modifier])
search_modifier:
  {
       IN NATURAL LANGUAGE MODE
     | IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION
     | IN BOOLEAN MODE
     | WITH QUERY EXPANSION
  }


使用举例如下:

-- 插入数据
insert into testTable values
(1,0,'11','zhangsan'),
(2,0,'11','zhangsanlisi'),
(3,0,'11','zhangsanlisiwangwu'),
(4,0,'11','zhangsanlisiwangwuzhaoli'),
(5,0,'11','zhangsanlisiwangwuzhaoliqianqizhangsan');
-- 使用布尔模式进行模糊匹配查找
select * from testTable where MATCH(column9) against('zhang*' in boolean mode);


上面的执行截图:


e32e120e8a774a6c9011b7c14b01f553.png



6.空间索引


空间索引只能针对空间类型的字段进行建立,mysql中的空间索引和全文索引实现都不是BTREE,所以即使是INNODB也存在多种不同的索引数据结构。mysql的空间类型和对应的索引使用范围不广。


mysql中的空间数据类型有4种,分别是GEOMETRY、POINT、LINESTRING、POLYGON。创建空间索引的列,必须将其声明为NOT NULL。


空间索引的建立:

-- 方式一
create spatial index colu8_idx on testTable(column8) comment '空间索引';
-- 方式二
alter table testTable add spatial index colu8_idx(column8) comment '空间索引';
-- 方式三
drop table if exists testTable;
create table testTable(
id tinyint  comment 'id',
column1 tinyint not null comment '列1',
column2 BIGINT not null comment '列2',
column3 MEDIUMINT not null comment '列3',
column4 DATETIME not null comment '列4',
column5 date not null comment '列5',
column6 TIMESTAMP not null comment '列6',
column7 year not null comment '列7',
column8 GEOMETRY not null comment '列8',
column9 varchar(20)  not null comment '列9',
-- PRIMARY key(id) using BTREE comment '主键',
PRIMARY key(id,column1) using BTREE comment '复合主键',
UNIQUE key colu1_idx(column1) using BTREE comment '唯一索引',
UNIQUE key colu1_cdx(column1,column2) using BTREE comment '复合唯一索引',
index colu3_idx(column3) using BTREE comment '普通索引1',
index dolu3_cdx(column3,column4) using BTREE comment '复合普通索引1',
fulltext colu9_idx(column9) comment '全文索引',
SPATIAL index colu8_idx(column8) comment '空间索引'
);


空间索引的删除和查看等都和普通索引没有什么区别,这里就不重复写入了。


三、总结



这里介绍的都是基础的索引的增删改查,和一些索引使用的案例以及注意事项。我们常用的其实还是主键索引、唯一索引、普通索引,复合索引、前缀索引(字符串或者二进制类型建立普通索引时可以建立前缀索引),其他的全文和空间索引其实是不常用的。这里列出来作为了解吧。


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
SQL 关系型数据库 MySQL
深入解析MySQL的EXPLAIN:指标详解与索引优化
MySQL 中的 `EXPLAIN` 语句用于分析和优化 SQL 查询,帮助你了解查询优化器的执行计划。本文详细介绍了 `EXPLAIN` 输出的各项指标,如 `id`、`select_type`、`table`、`type`、`key` 等,并提供了如何利用这些指标优化索引结构和 SQL 语句的具体方法。通过实战案例,展示了如何通过创建合适索引和调整查询语句来提升查询性能。
177 9
|
17天前
|
SQL 存储 关系型数据库
MySQL秘籍之索引与查询优化实战指南
最左前缀原则。不冗余原则。最大选择性原则。所谓前缀索引,说白了就是对文本的前几个字符建立索引(具体是几个字符在建立索引时去指定),比如以产品名称的前 10 位来建索引,这样建立起来的索引更小,查询效率更快!
81 22
 MySQL秘籍之索引与查询优化实战指南
|
26天前
|
存储 缓存 关系型数据库
【MySQL进阶篇】存储引擎(MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案)
MySQL的存储引擎是其核心组件之一,负责数据的存储、索引和检索。不同的存储引擎具有不同的功能和特性,可以根据业务需求 选择合适的引擎。本文详细介绍了MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案。
【MySQL进阶篇】存储引擎(MySQL体系结构、InnoDB、MyISAM、Memory区别及特点、存储引擎的选择方案)
|
18天前
|
存储 关系型数据库 MySQL
MySQL中为什么要使用索引合并(Index Merge)?
通过这些内容的详细介绍和实际案例分析,希望能帮助您深入理解索引合并及其在MySQL中的
69 10
|
1月前
|
存储 Oracle 关系型数据库
索引在手,查询无忧:MySQL索引简介
MySQL 是一款广泛使用的关系型数据库管理系统,在2024年5月的DB-Engines排名中得分1084,仅次于Oracle。本文介绍MySQL索引的工作原理和类型,包括B+Tree、Hash、Full-text索引,以及主键、唯一、普通索引等,帮助开发者优化查询性能。索引类似于图书馆的分类系统,能快速定位数据行,极大提高检索效率。
60 8
|
26天前
|
存储 关系型数据库 MySQL
【MYSQL】 ——索引(B树B+树)、设计栈
索引的特点,使用场景,操作,底层结构,B树B+树,MYSQL设计栈
|
1天前
|
缓存 关系型数据库 MySQL
【深入了解MySQL】优化查询性能与数据库设计的深度总结
本文详细介绍了MySQL查询优化和数据库设计技巧,涵盖基础优化、高级技巧及性能监控。
12 0
|
28天前
|
存储 Oracle 关系型数据库
数据库传奇:MySQL创世之父的两千金My、Maria
《数据库传奇:MySQL创世之父的两千金My、Maria》介绍了MySQL的发展历程及其分支MariaDB。MySQL由Michael Widenius等人于1994年创建,现归Oracle所有,广泛应用于阿里巴巴、腾讯等企业。2009年,Widenius因担心Oracle收购影响MySQL的开源性,创建了MariaDB,提供额外功能和改进。维基百科、Google等已逐步替换为MariaDB,以确保更好的性能和社区支持。掌握MariaDB作为备用方案,对未来发展至关重要。
59 3
|
28天前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
70 3
|
28天前
|
SQL 关系型数据库 MySQL
数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog
《数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog》介绍了如何利用MySQL的二进制日志(Binlog)恢复误删除的数据。主要内容包括: 1. **启用二进制日志**:在`my.cnf`中配置`log-bin`并重启MySQL服务。 2. **查看二进制日志文件**:使用`SHOW VARIABLES LIKE 'log_%';`和`SHOW MASTER STATUS;`命令获取当前日志文件及位置。 3. **创建数据备份**:确保在恢复前已有备份,以防意外。 4. **导出二进制日志为SQL语句**:使用`mysqlbinlog`
88 2