mysql聚簇索引和非聚簇索引

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: mysql聚簇索引和非聚簇索引

引语

这篇文章主要介绍mysql中innodb的聚簇索引和非聚簇索引,那首先我们要先看下聚簇索引和非聚簇索引的概念是什么,是干什么用的.

聚簇索引和非聚簇索引的概念

我们先引用官网上的一段话来看看它们是干嘛的

Every InnoDB table has a special index called the clustered index where the data for the rows is stored. Typically, the clustered index is synonymous with the primary key. To get the best performance from queries, inserts, and other database operations, you must understand how InnoDB uses the clustered index to optimize the most common lookup and DML operations for each table.

When you define a PRIMARY KEY on your table, InnoDB uses it as the clustered index. Define a primary key for each table that you create. If there is no logical unique and non-null column or set of columns, add a new auto-increment column, whose values are filled in automatically.

If you do not define a PRIMARY KEY for your table, MySQL locates the first UNIQUE index where all the key columns are NOT NULL and InnoDB uses it as the clustered index.

If the table has no PRIMARY KEY or suitable UNIQUE index, InnoDB internally generates a hidden clustered index named GEN_CLUST_INDEX on a synthetic column containing row ID values. The rows are ordered by the ID that InnoDB assigns to the rows in such a table. The row ID is a 6-byte field that increases monotonically as new rows are inserted. Thus, the rows ordered by the row ID are physically in insertion order.

有耐性的朋友可以自己翻译看看,这里咱们大概翻译了一下,总结出上面这段话的意思:
每个InnoDB表都有一个特殊的索引,称为聚簇索引,用于存储行数据。
1.如果创建了一个主键,InnoDB会将其用作聚簇索引(如果主键没有逻辑唯一且非空的列或列集,最好是设置成自动递增的)
2.如果没有为表创建主键,则MySQL会在所有键列都不为NULL的情况下找到第一个UNIQUE索引,InnoDB会将其用作聚集索引
3.如果表没有PRIMARY KEY或合适的UNIQUE索引,则InnoDB在包含行ID值的合成列上内部生成一个名为GEN_CLUST_INDEX的隐藏的聚集索引(隐藏的是看不到的,也就是说不会出现在desc table中,行ID是一个6字节的字段,随着插入新行而单调增加)
从这三种情况来看的话,就是说不管你有没有创建主键,mysql都会给你弄一个聚簇索引给安排上,你创建了就用你设置的主键为聚簇索引,没有创建就给你来个隐藏的.

聚簇索引(也称为主键索引)就是携带了行数据的索引,非聚簇索引就是除了聚簇索引之外的索引.这样说起来可能有点干巴巴的,咱们画个图来理解一下.
假设有一张表test

create table test(
id int primary key,
age int not null,
name varchar(16),
PRIMARY KEY (`id`),
KEY `idx_age` (`age`) USING BTREE,
KEY `idx_name` (`name`) USING BTREE,
)engine=InnoDB;

主键是id,然后有两个普通索引idx_age,idx_name(btree类型的索引),使用的是innodb引擎.
我们知道id就是聚簇索引,idx_age,idx_name是非聚簇索引.
现在有三条数据(1,11,'甲'),(2,12,'乙'),(2,13,'丙').那么他们在数据库中存储的形式是,如下:
聚簇索引:

非聚簇索引:

可以看到聚簇索引后面是直接跟着的数据,而非聚簇索引指向的是聚簇索引的key值.
因此非聚簇索引查询数据需要先查到聚簇索引的key,然后用这个key去查询真正的数据(这个过程称为回表).
也就是说非聚簇索引是需要查询两次
如图:

所以能走聚簇索引的尽量走聚簇索引(也可以说是尽量走主键),看起来都是走索引,实际上主键要更快.
而且主键索引如果是自增的int类型,因为长度比较小,占用的空间也比较小.

覆盖索引

我们上面说到如果是非聚簇索引的话会需要回表,查询两次,但是如果要查询得字段,数据直接就在索引上是可以不需要回表的.这种索引称为覆盖索引.
比如我们要查询上面的test表中的age和name两个字段.

select id,age,name from test where age = 13;

直接查询的话,会根据age的索引找到id的key,然后再用id去查询出数据.
但是如果我们创建一个(age,name)的联合索引,情况就不一样了.

因为要返回的值,id在联合索引指向的key上,age和name共同组成了联合索引,
因此数据都在(age,name)的联合索引上,并不需要回表在去查询一次,可以大大提高查询得效率.
当然这个查询要比较频繁,使用率比较高,毕竟创建索引也是要消耗资源的,实际情况要根据查询频率和索引大小来做出判断.
有联合索引存在的情况下能走覆盖索引当然是最好的,提高了查询效率.
__注:还有在某些count聚合函数使用的时候可以使用覆盖索引来优化count,比如说select count(age) from test.
因为age是有索引了,直接使用到的也是age,所以覆盖索引了,无需回表.__

总结:

1.聚簇索引和非聚簇索引,查询得时候使用聚簇索引能提高查询效率,尽量避免走非聚簇索引回表的耗时操作
2.覆盖索引能提高查询效率,主要是避免了回表的操作,查询得时候根据具体情况建立合适的索引走覆盖索引提高查询速度

参考资料:

1.https://dev.mysql.com/doc/refman/5.6/en/innodb-index-types.html
2.https://mp.weixin.qq.com/s/y0pjtNUZhOW2ZBOy4m-xsA

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
缓存 关系型数据库 MySQL
MySQL索引策略与查询性能调优实战
在实际应用中,需要根据具体的业务需求和查询模式,综合运用索引策略和查询性能调优方法,不断地测试和优化,以提高MySQL数据库的查询性能。
196 66
|
15天前
|
SQL 关系型数据库 MySQL
深入解析MySQL的EXPLAIN:指标详解与索引优化
MySQL 中的 `EXPLAIN` 语句用于分析和优化 SQL 查询,帮助你了解查询优化器的执行计划。本文详细介绍了 `EXPLAIN` 输出的各项指标,如 `id`、`select_type`、`table`、`type`、`key` 等,并提供了如何利用这些指标优化索引结构和 SQL 语句的具体方法。通过实战案例,展示了如何通过创建合适索引和调整查询语句来提升查询性能。
117 9
|
3月前
|
存储 关系型数据库 MySQL
阿里面试:为什么要索引?什么是MySQL索引?底层结构是什么?
尼恩是一位资深架构师,他在自己的读者交流群中分享了关于MySQL索引的重要知识点。索引是帮助MySQL高效获取数据的数据结构,主要作用包括显著提升查询速度、降低磁盘I/O次数、优化排序与分组操作以及提升复杂查询的性能。MySQL支持多种索引类型,如主键索引、唯一索引、普通索引、全文索引和空间数据索引。索引的底层数据结构主要是B+树,它能够有效支持范围查询和顺序遍历,同时保持高效的插入、删除和查找性能。尼恩还强调了索引的优缺点,并提供了多个面试题及其解答,帮助读者在面试中脱颖而出。相关资料可在公众号【技术自由圈】获取。
|
3月前
|
SQL 关系型数据库 MySQL
案例剖析:MySQL唯一索引并发插入导致死锁!
案例剖析:MySQL唯一索引并发插入导致死锁!
226 0
案例剖析:MySQL唯一索引并发插入导致死锁!
|
20天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化以及慢查询优化
通过本文的介绍,希望您能够深入理解MySQL索引优化和慢查询优化的方法,并在实际应用中灵活运用这些技术,提升数据库的整体性能。
59 18
|
12天前
|
存储 Oracle 关系型数据库
索引在手,查询无忧:MySQL索引简介
MySQL 是一款广泛使用的关系型数据库管理系统,在2024年5月的DB-Engines排名中得分1084,仅次于Oracle。本文介绍MySQL索引的工作原理和类型,包括B+Tree、Hash、Full-text索引,以及主键、唯一、普通索引等,帮助开发者优化查询性能。索引类似于图书馆的分类系统,能快速定位数据行,极大提高检索效率。
45 8
|
19天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化以及慢查询优化
通过本文的介绍,希望您能够深入理解MySQL索引优化和慢查询优化的方法,并在实际应用中灵活运用这些技术,提升数据库的整体性能。
22 7
|
18天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化与慢查询优化:原理与实践
通过本文的介绍,希望您能够深入理解MySQL索引优化与慢查询优化的原理和实践方法,并在实际项目中灵活运用这些技术,提升数据库的整体性能。
50 5
|
22天前
|
存储 关系型数据库 MySQL
Mysql索引:深入理解InnoDb聚集索引与MyisAm非聚集索引
通过本文的介绍,希望您能深入理解InnoDB聚集索引与MyISAM非聚集索引的概念、结构和应用场景,从而在实际工作中灵活运用这些知识,优化数据库性能。
93 7
|
7天前
|
存储 关系型数据库 MySQL
【MYSQL】 ——索引(B树B+树)、设计栈
索引的特点,使用场景,操作,底层结构,B树B+树,MYSQL设计栈