百万数据查询优化(MySQL 百万数据分页优化 26 秒 到 01 秒的方案覆盖索引子查询)

百万数据查询优化(MySQL 百万数据分页优化 26 秒 到 01 秒的方案覆盖索引子查询)

adminqwq 2026-02-27 信息披露 3 次浏览 0个评论
问题

用户表(t_user)结构如下图,有500万数据,进行分页查询,每页5条,要查询第100001页数据。

MySQL 百万数据分页优化: 2.6 秒 到 0.1 秒的方案(覆盖索引 + 子查询)

MySQL 百万数据分页优化: 2.6 秒 到 0.1 秒的方案(覆盖索引 + 子查询)

MySQL 百万数据分页优化: 2.6 秒 到 0.1 秒的方案(覆盖索引 + 子查询)

问题说明

查询耗时2.6秒,而且还用到了 filesort(此处不再深究究竟是在内存里排序的 还是用到了磁盘排序),整个查询效能较低。

问题分析:

A、对于表 student,id是主键、name字段建立了普通索引,那么在 student.ibd 里就有两棵 B+T树:一棵是主键索引树,它是一个聚集索引,叶子节点上有所有字段;另一棵是用name字段建立的二级索引,它是一个非聚集索引,叶子节点上只有name和id。

B、字段 name 建立了普通索引,此处又是根据name进行排序,感觉这里应该正好可以用上第二棵B+树,但是Explanin结果发现Type是All,也就是走了全表扫描,对主键索引树进行了整棵树的扫描,怪不得效能不好,但这是为什么呢???答案是:因为还查询了remark字段,remark字段不在二级索引树里无法通过覆盖索引的方式查询,MySQL考虑到回表的代价就直接去主键索引树里查了,查出前500005条来然后根据name外部排序然后去掉前500000条,效能较低。

改进方式MySQL 百万数据分页优化: 2.6 秒 到 0.1 秒的方案(覆盖索引 + 子查询)

MySQL 百万数据分页优化: 2.6 秒 到 0.1 秒的方案(覆盖索引 + 子查询)

结果:耗时0.1秒,效能非常高;我们继续通过Explain分析其查询方式。

根据规则(id大的先执行,id一样的从上往下执行)得出查询步骤:

1、先构造子查询,根据name排序只查询id,通过覆盖索引的方式去二级索引里查询出符合条件的5个用户ID;此步只对用name建立的普通索引进行了快速扫描。

2、然后再拿着这5个ID通过主键索引树上进行主键快速定位,查询出需要的字段。

注:改进后的这种方式的核心思想是减少扫描行数。仔细想想,这是一种思路,其实不只是在分页查询时可以用,在其他地方也可以用。

转载请注明来自海坡下载,本文标题:《百万数据查询优化(MySQL 百万数据分页优化 26 秒 到 01 秒的方案覆盖索引子查询)》

每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,3人围观)参与讨论

还没有评论,来说两句吧...