分布式任务调度内的 MySQL 分页查询优化 等值在前,排序在中间,范围在最后

分布式任务调度内的 MySQL 分页查询优化 https://mp.weixin.qq.com/s/VhSzxYIRv83T3D3JD4cORg

三、优化方案

 

3.1 优化方案确定

 

当前SQL执行计划以主键进行顺序遍历,是一个范围扫描,有点像在一片很大的居民区按照序号挨家挨户寻找一些特定的人一样,比较简单也比较低效。

 

既然查询是以is_deleteduser_type为主要的过滤条件,查询特定的人群信息,可以考虑直接在这两列上添加索引,记录特定人群信息的位置,根据位置直接去定向寻找。

 

虽然is_deleteduser_type字段区分度很低,但是成为有序结构,能避免这条SQL大量的读取不符合条件的数据的行为,添加索引的收益远大于索引带来负面影响。

 

最终的添加的索引:

alter table test_user add index idx_isdeleted_usertype_id(is_deleted,user_type,id);

 

添加该索引的考虑:遵循ESR原则(等值在前,排序在中间,范围在最后),既能高效扫描到对应的数据,还能避免id的排序,extra内显示使用了Using index condition。

mysql>  explain select id,uuid,name,user_type,is_deleted,modify_date from test_user where is_deleted=0 and user_type=2 and id > 0 and id % 10 = 9 order by id limit 500;
+----+-------------+-----------+------------+-------+-----------------------------------+---------------------------+---------+------+------+----------+-----------------------+
| id | select_type | table     | partitions | type  | possible_keys                     | key                       | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-----------+------------+-------+-----------------------------------+---------------------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | test_user | NULL       | range | PRIMARY,idx_isdeleted_usertype_id | idx_isdeleted_usertype_id | 10      | NULL |  999 |   100.00 | Using index condition |
+----+-------------+-----------+------------+-------+-----------------------------------+---------------------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)  

 

3.2 优化效果对比

 

优化前:

# Query_time: 6.981938  Lock_time: 0.000076 Rows_sent: 100  Rows_examined: 17890145
SET timestamp=1695711818;
select id,uuid,name,user_type,is_deleted,modify_date from test_user where is_deleted=0 and user_type=2 and id > 0 and id % 10 = 9 order by id limit 500;

 

优化后:

# Query_time: 0.000884  Lock_time: 0.000091 Rows_sent: 100  Rows_examined: 100
SET timestamp=1695714485;
select id,uuid,name,user_type,is_deleted,modify_date from test_user where is_deleted=0 and user_type=2 and id > 0 and id % 10 = 9 order by id limit 500;

 

优化提升:

扫描行数从1700w条降低为100条,查询时间从6.98s 降低为 0.8ms

 

2.3  图示的优化后的SQL执行过程

  1. 通过idx_isdeleted_usertype_id索引的有序性,进行二分查找,快速定位到满足is_deleted和user_type、id条件主键信息。

  2. 通过主键信息回表读取完整的数据。

  3. 返回数据给客户端服务。

 

 

 

 

posted @   papering  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2023-05-23 软件 授权 加密 加固
2022-05-23 Lock-free Observations for Prometheus Histograms
2022-05-23 RVA relative virtual address PE
2022-05-23 VMA anonymous virtual memory area 匿名虚拟内存区域
2019-05-23 redis incr incrby decr decrby命令 原理
2018-05-23 任何不看源码的代码引入都是存在定时爆炸的可能
2018-05-23 博客数计数
点击右上角即可分享
微信分享提示