1000 万数据重刷遇坑:老程序员也常忽略的分页查询陷阱与优化(下)

在上一篇文章《1000 万数据重刷遇坑:老程序员也常忽略的分页查询陷阱与优化(上)》中,我们提到了使用游标分页的方式去优化千万数据的查询。游标分页的方式虽然可以有效的减少查询时间,但是其不支持跳页

现在有这样一个场景:某公司拥有上千万的客户数据,其中有600多万的客户数据出现了异动,后端需要基于一定逻辑去刷新这些数据。

业务层的代码见《1000 万数据重刷遇坑:老程序员也常忽略的分页查询陷阱与优化(上)》。本文重点分析SQL。

以下是原始SQL。

SELECT * FROM customer LIMIT #{pageNo}, #{pageSize};

直接说结论,使用覆盖索引来优化该SQL

以下是优化后的SQL。

SELECT * FROM customer
JOIN (
    SELECT id FROM customer ORDER BY id LIMIT #{pageNo}, #{pageSize}
) AS c USING (id);

或者

SELECT * FROM customer c1
JOIN (
    SELECT id FROM customer ORDER BY id LIMIT #{pageNo}, #{pageSize}
) AS c2 on c1.id = c2.id);

这两个SQL查询在逻辑是等价的,最终的执行结果也是一样,唯一的区别就是语法。

为什么覆盖索引可以优化?

按照惯例,我们使用explain命令来查看下它们的执行情况。

explain
SELECT * FROM customer LIMIT 20,500
[2025-03-03 22:35:28] 1 row retrieved starting from 1 in 468 ms (execution: 141 ms, fetching: 327 ms)

原SQL耗费468ms。

explain
SELECT * FROM customer join (select id from customer order by id LIMIT 20,500) as t using(id)
[2025-03-03 22:39:19] 3 rows retrieved starting from 1 in 170 ms (execution: 118 ms, fetching: 52 ms)

使用覆盖索引的SQL耗时170ms,相比原SQL减少了298ms。性能提升快2倍。

在这里插入图片描述
由此可知,本SQL涉及一个主查询和一个派生查询,主查询分为两部分,一部分是对派生查询的结果(derived2)进行了全表扫描,预计需要检查520行数据。另一部分访问了customer表,使用了唯一索引查找(eq_ref),这是非常高效的访问类型,并用派生查询结果中的id列来关联。

派生查询也访问了customer,使用了覆盖索引,即查询所需的数据都在索引中,不需要回表查询,提升了查询效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

coding侠客

一起充电,一起成长。

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

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

打赏作者

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

抵扣说明:

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

余额充值