索引的分类和回表查询——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;

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

相关推荐
Tanecious.6 分钟前
机器视觉--python基础语法
开发语言·python
叠叠乐12 分钟前
rust Send Sync 以及对象安全和对象不安全
开发语言·安全·rust
战族狼魂42 分钟前
CSGO 皮肤交易平台后端 (Spring Boot) 代码结构与示例
java·spring boot·后端
Tttian6222 小时前
Python办公自动化(3)对Excel的操作
开发语言·python·excel
xyliiiiiL2 小时前
ZGC初步了解
java·jvm·算法
杉之2 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
hycccccch3 小时前
Canal+RabbitMQ实现MySQL数据增量同步
java·数据库·后端·rabbitmq
独好紫罗兰3 小时前
洛谷题单2-P5713 【深基3.例5】洛谷团队系统-python-流程图重构
开发语言·python·算法
天天向上杰4 小时前
面基JavaEE银行金融业务逻辑层处理金融数据类型BigDecimal
java·bigdecimal
闪电麦坤954 小时前
C#:base 关键字
开发语言·c#