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

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
简介: 什么是索引?索引的作用,有无索引的区别。

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


一、索引基础:增删改查



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


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 '空间索引'
);


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


三、总结



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


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
8月前
|
关系型数据库 MySQL 分布式数据库
安全可靠的PolarDB V2.0 (兼容MySQL)产品能力及应用场景
PolarDB分布式轻量版采用软件输出方式,能够部署在您的自主环境中。PolarDB分布式轻量版保留并承载了云原生数据库PolarDB分布式版技术团队深厚的内核优化成果,在保持高性能的同时,显著降低成本。
691 140
|
8月前
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
6月前
|
SQL 监控 关系型数据库
MySQL事务处理:ACID特性与实战应用
本文深入解析了MySQL事务处理机制及ACID特性,通过银行转账、批量操作等实际案例展示了事务的应用技巧,并提供了性能优化方案。内容涵盖事务操作、一致性保障、并发控制、持久性机制、分布式事务及最佳实践,助力开发者构建高可靠数据库系统。
|
8月前
|
存储 关系型数据库 MySQL
MySQL数据库索引的数据结构?
MySQL中默认使用B+tree索引,它是一种多路平衡搜索树,具有树高较低、检索速度快的特点。所有数据存储在叶子节点,非叶子节点仅作索引,且叶子节点形成双向链表,便于区间查询。
229 4
|
6月前
|
存储 关系型数据库 MySQL
MySQL中的int(10)、char(10)与varchar(10)的类型和区别
在选择正确的数据类型时,需要仔细考虑每列的数据特点及应用程序的使用情况。合理的数据类型选择可以优化存储空间的使用,提高查询速度和数据库的整体性能。
658 14
|
7月前
|
存储 关系型数据库 MySQL
MYSQL数据加密压缩函数应用实战指南。
总的来说,加密和压缩是维护MySQL数据库中数据安全性和效率的有效手段。使用时需权衡性能与安全,合理应用加密和压缩函数。在设计数据库架构时要考虑到加密字段的查询性能,因为加密可能使得一些索引失效。压缩数据能有效减少存储空间的占用,但在服务器负载较高时应避免实时压缩和解压,以免影响总体性能。
230 10
|
7月前
|
存储 关系型数据库 MySQL
MySQL数据库中的 char 与 varchar的区别是什么
MySQL中的char和varchar均用于存储字符串,但有显著区别。char为定长类型,固定长度,存储空间始终为设定值,适合长度固定的数据如手机号。varchar为变长类型,仅占用实际数据所需空间,适合长度不固定的内容如用户名。二者在性能与空间利用上各有优劣,应根据实际场景合理选择。
501 0
|
8月前
|
存储 SQL 关系型数据库
MySQL 核心知识与索引优化全解析
本文系统梳理了 MySQL 的核心知识与索引优化策略。在基础概念部分,阐述了 char 与 varchar 在存储方式和性能上的差异,以及事务的 ACID 特性、并发事务问题及对应的隔离级别(MySQL 默认 REPEATABLE READ)。 索引基础部分,详解了 InnoDB 默认的 B+tree 索引结构(多路平衡树、叶子节点存数据、双向链表支持区间查询),区分了聚簇索引(数据与索引共存,唯一)和二级索引(数据与索引分离,多个),解释了回表查询的概念及优化方法,并分析了 B+tree 作为索引结构的优势(树高低、效率稳、支持区间查询)。 索引优化部分,列出了索引创建的六大原则
196 2
|
6月前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
468 158
|
6月前
|
关系型数据库 MySQL 数据库
自建数据库如何迁移至RDS MySQL实例
数据库迁移是一项复杂且耗时的工程,需考虑数据安全、完整性及业务中断影响。使用阿里云数据传输服务DTS,可快速、平滑完成迁移任务,将应用停机时间降至分钟级。您还可通过全量备份自建数据库并恢复至RDS MySQL实例,实现间接迁移上云。

推荐镜像

更多