索引的分类和回表查询——Java全栈知识(29)

索引的分类和回表查询

Mysql 的索引按照类型可以分为以下几类,但是我们使用的 InnoDB 只支持主键索引,唯一索引,普通索引,并不支持全文索引。

1、聚集索引和二级索引

InnoDB 可以将索引分为两类分别是聚集索引和二级索引,也可以叫做聚簇索引和非聚簇索引。

聚集索引的叶子节点存储的是一整行的数据。

二级索引的叶子节点存储的是该行的主键。

聚集索引选取规则:

  • 如果存在主键,主键索引就是聚集索引。
  • 如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引。
  • 如果表没有主键,或没有合适的唯一索引,则 InnoDB 会自动生成一个 rowid 作为隐藏的聚集索引。

2、覆盖索引和回表查询

覆盖索引是指查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到。

例如:

我们针对这张表创建两个索引,分别是 id 为主键索引(默认),name 字段为普通索引。

sql 复制代码
select * from tb_user where id = 1
select id,name from tb_user where name = 'Arm'
select id,name,gender from tb_user where name = 'Arm'

1、sql 1 需要查询所有字段,可以使用主键索引,查询到所有字段,因为主键索引是聚集索引,也就是说该行的所有字段都在主键索引的叶子节点上,自然我们能就可以使用 id 查到索引中包含的所有的列,是覆盖索引。

2、sql 2 中我们只查询了 id 和 name 两个字段,查询条件是 name 字段,name 字段我们创建了普通索引,上面我们讲了普通索引是二级索引,叶子节点上的数据只有 id,索引本身包含了 name 字段。所以也可以返回需要的所有的列,是覆盖索引。

3、sql 3 中我们需要查询 id,name 和 gender 三个字段,条件是 name 字段,走普通索引,但是由于索引上我们只能找到 id 和 name 两个字段。所以我们还需要拿查找到的 id 去主键索引上进行二次查找,才能找到对应的 gender 字段。这个就叫做回表查询

3、超大分页优化

超大分页问题就是我们在使用 limit 关键字的时候,例如我们的表中有 10w 条数据, limit 0,10 分页获取前十条数据,这样查询非常快。

但是如果 limit 99990,10 去获取最后十条数据的时候,运行速度就变得非常的慢了。

因为 limit 在使用的时候,针对于分页的数据会进行遍历。所以获取越往后的数据,效率就越低。

优化思路: 一般分页查询时,通过创建覆盖索引能够比较好地提高性能,可以通过覆盖索引加子查询形式进行优化

sql 复制代码
select * from tb_sku t,  (select id from tb_sku order by id limit 9000000,10) a where t.id = a.id;

因为索引自带排序功能,这样就不需要进行遍历了。

相关推荐
郝学胜-神的一滴18 分钟前
Qt QPushButton 样式完全指南:从基础到高级实现
linux·开发语言·c++·qt·程序人生
沐知全栈开发22 分钟前
R MySQL 连接
开发语言
tryxr30 分钟前
变量捕获相关内容
java·开发语言·jvm
拉不动的猪41 分钟前
Token无感刷新全流程(Vue + Axios + Node.js(Express))
java·javascript·vue.js
百锦再41 分钟前
大型省级政务平台采用金仓数据库(KingbaseES)
开发语言·数据库·后端·rust·eclipse
m0_639817151 小时前
基于springboot个人云盘管理系统【带源码和文档】
java·spring boot·后端
biter down1 小时前
C 语言17:位操作符 & | ^:从二进制编码到大小端
c语言·开发语言
大头an1 小时前
Spring事务隔离级别全解析:从读未提交到序列化
java
mjhcsp1 小时前
C++ map 容器:有序关联容器的深度解析与实战
开发语言·c++·map
将编程培养成爱好1 小时前
C++ 设计模式《账本事故:当备份被删光那天》
开发语言·c++·设计模式·备忘录模式