Mysql索引的优点、缺点、分类及使用方法

本文详细介绍了Mysql索引的分类(如普通索引、唯一索引、主键索引、全文索引和空间索引),创建方式,以及它们在数据库性能优化中的作用。此外,涵盖了索引的物理实现(聚簇索引与非聚簇索引)、字段个数分类(单列索引和联合索引)以及常见的索引操作,如删除、查看和性能分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一、前言

1.索引是一种可以帮助 Mysql 高效获取数据的数据结构,目的是为了减少磁盘I/O次数,加快查询速度
2.索引是在存储引擎中实现的,每种存储引擎实现索引的方式可能不通,其中Mysql的InnoDB引擎的索引底层采用B+树算法实现
3.所有存储引擎支持每个表至少16个索引,总索引长度至少为256个字节


二、优点

1.降低数据库I/O成本
2.对有依赖关系的子表和父表联合查询时,可以提高查询速度
3.在使用 group by 或者 order by 查询数据时,可以显著减少分组和排序的时间


三、缺点

1.创建和维护索引会耗费时间
2.索引存储文件会占用磁盘空间
3.大大提高表查询效率的同时会降低表更新效率【增删改的效率会被降低】


四、分类及创建方式

1.功能上分类

<1>普通索引

不附加任何限制条件,只用于提高查询效率,可以在任何字段上创建

# 建表时创建索引
CREATE TABLE book (
    id int NOT NULL AUTO_INCREMENT,
    title varchar(255) DEFAULT NULL,
    author varchar(50) DEFAULT NULL,
    PRIMARY KEY (`id`) USING BTREE,
  
    # title字段创建普通索引 ---
    INDEX idx_title(title)
    # ----------------------
  
);


# 为已创建的表添加索引
ALTER TABLE book ADD INDEX idx_title(title);
# 或者
CREATE INDEX idx_title ON book(title);

<2>唯一索引

字段添加 UNIQUE 参数即设置为唯一索引,该索引字段必须唯一,但可以有空值,一张数据表可以有多个唯一索引

# 建表时创建索引
CREATE TABLE book (
    id int NOT NULL AUTO_INCREMENT,
    title varchar(255) DEFAULT NULL,
    author varchar(50) DEFAULT NULL,
    PRIMARY KEY (`id`) USING BTREE,
  
    # title字段创建唯一索引 --------
    # 作用于电话号码、身份证号等字段时很实用
    UNIQUE INDEX idx_title(title)
    # ----------------------------
  
);

# 为已创建的表添加索引
ALTER TABLE book ADD UNIQUE INDEX idx_title(title);
# 或者
CREATE UNIQUE INDEX idx_title ON book(title);

<3>主键索引

主键索引是一种特殊的唯一索引,在主键索引的基础上增加不为空的约束,也就是 NOT NULL + UNIQUE ,一张表只能有一个主键索引

# 建表时创建索引
CREATE TABLE book (

	# 创建主键索引 ---------------------
    id int PRIMARY KEY AUTO_INCREMENT,
    # --------------------------------
  
    title varchar(255) DEFAULT NULL,
    author varchar(50) DEFAULT NULL,
    PRIMARY KEY (`id`) USING BTREE, 
);

<4>全文索引

字段添加 FULLTEXT 可以设置为全文索引,只能创建在 char、vachar 或 text 类型的字段上,查询数据量较大的文本信息时可以提高查询速度【不过当数据量巨大的时候,还是需要用ElasticSearch】

# 建表时创建索引
CREATE TABLE book (
    id int NOT NULL AUTO_INCREMENT,
    title varchar(255) DEFAULT NULL,
    author varchar(50) DEFAULT NULL,
    PRIMARY KEY (`id`) USING BTREE,
  
    # title字段创建全文索引 --------------------
    # 使用title字段的前50个字符创建全文索引
	FULLTEXT INDEX futxt_idx_title(title(50))
    # ---------------------------------------
  
);

# 为已创建的表添加索引
ALTER TABLE book ADD FULLTEXT INDEX futxt_idx_title(title(50));
# 或者
CREATE FULLTEXT INDEX futxt_idx_title ON book(title(50));

# 检索方式
SELECT * FROM book WHERE MATCH(title) AGAINST ("白夜行")
# 建表时创建索引
CREATE TABLE book (
    id int NOT NULL AUTO_INCREMENT,
    title varchar(255) DEFAULT NULL,
    author varchar(50) DEFAULT NULL,
    PRIMARY KEY (`id`) USING BTREE,
  
    # title字段创建全文索引 ------------------------------
    # 使用title、author字段创建全文索引
	FULLTEXT INDEX futxt_idx_title_author(title, author)
    # --------------------------------------------------
  
);

# 为已创建的表添加索引
ALTER TABLE book ADD FULLTEXT INDEX futxt_idx_title_author(title, author);
# 或者
CREATE FULLTEXT INDEX futxt_idx_title_author ON book(title, author);

# 检索方式
SELECT * FROM book WHERE MATCH(title, author) AGAINST ("白夜行")

<5>空间索引

InnoDB不支持,本人水平有限暂时没用到,就不做阐述了


2.物理实现上分类

InnoDB的索引分为两种

<1>聚簇索引

基于主键id搭建的B+树,索引和数据不分家,所有用户记录都保存在了叶子结点,可以说是 索引即数据,数据即索引
聚簇索引不需要用户显式的创建,而是插入数据的时候有数据引擎自动创建,正是因此,当id为查询条件时,查询速度会得到显著的提升
在这里插入图片描述

<2>非聚簇索引【二级索引、辅助索引】

基于指定字段搭建的B+树,仅有指定字段和主键,没有其他数据,索引和数据是分开的,当mysql根据指定字段的非聚簇索引找到对应数据后,需要通过非聚簇索引对应的主键在聚簇索引中查出数据【这个操作叫做回表】,可以说是 索引是索引,数据是数据【旺柴】
非聚簇索引需要用户显式创建
在这里插入图片描述
ps:非聚簇索引还有个特殊情况就是联合索引,是基于多个指定字段搭建的B+树,可提高多条件查询的效率

<3>二者区别

1.聚簇索引叶子结点存储的是数据,非聚簇索引叶子结点存储的是数据位置
2.一个表只能有一个聚簇索引【因为只能有一种排序存储方式】,但是可以有多个非聚簇索引
3.聚簇索引在查询时效率高【不需要进行回表查询】,非聚簇索引在增删改时效率高【不需要更新数据】


3.字段个数上分类

<1>单列索引

一个索引只对应一个字段【包括普通索引、唯一索引等】

# 建表时创建索引
CREATE TABLE book (
    id int NOT NULL AUTO_INCREMENT,
    title varchar(255) DEFAULT NULL,
    author varchar(50) DEFAULT NULL,
    PRIMARY KEY (`id`) USING BTREE,
  
    # title字段创建单列索引 ---
    INDEX idx_title(title)
    # ----------------------
  
);

# 为已创建的表添加索引
ALTER TABLE book ADD INDEX idx_title(title);
# 或者
CREATE INDEX idx_title ON book(title);

<2>联合索引

一个索引对应多个字段

# 建表时创建索引
CREATE TABLE book (
    id int NOT NULL AUTO_INCREMENT,
    title varchar(255) DEFAULT NULL,
    author varchar(50) DEFAULT NULL,
    PRIMARY KEY (`id`) USING BTREE,
  
    # title、author字段创建联合索引 -------
    INDEX mul_idx_title_author(title, author)
    # -----------------------------------
  
);

# 为已创建的表添加索引
ALTER TABLE book ADD INDEX mul_idx_title_author(title, author);
# 或者
CREATE INDEX mul_idx_title_author ON book(title, author);

重点:联合索引的多个字段在查询时一定要注意sql中的查询字段,比如上面那个联合索引,如果使用下面这种查询方法,实际上是用不到索引的

SELECT * FROM book WHERE author="东野圭吾";

但是下面这两条却可以用到索引

SELECT * FROM book WHERE title="白夜行";
SELECT * FROM book WHERE title="白夜行" and author="东野圭吾";

也就是说,创建联合索引时,是按照你给定的字段顺序创建B+树的,查询的时候后面的字段依赖于前面的字段【称为最左前缀原则】,如果只有后面的字段没有前面的字段,那么查询时将不会使用索引


五、其他操作

1.删除索引

# 删除 book 表的 idx_title 索引
DROP INDEX idx_title ON book

2.查看索引

# 查看 book 表已创建的索引
SHOW INDEX FROM book;

3.查看某条sql是否用到了索引

# 性能分析工具,可以查看这条sql是否用到了索引
EXPLAIN SELECT * FROM book WHERE title = "高等数学";

在这里插入图片描述


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

什么都干的派森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值