MySQL百万级数据排序分页查询

1. 需求

按照成绩降序排序,查询字段学号(id),姓名(name),分数(score),带排序的分页查询

数据大小:五百万条

2. 初始状态

浅分页:

# 浅分页
EXPLAIN
SELECT id, name, score from student order by score desc limit 5, 20;

执行效率:执行的为一个全表扫描,并且会额外执行Using filesort

Using filesort表示在索引之外,需要额外进行外部的排序动作。导致该问题的原因一般和order by有者直接关系,一般可以通过合适的索引减少或者避免

执行时间:1.394s

深分页:

# 深分页
EXPLAIN
SELECT id, name, score from student order by score desc limit 4500000, 20;

执行效率:和浅分页一样

执行时间:6.071s

结论: 无论深分页还是浅分页,执行时间都是非常长的,并且深分页比浅分页的时间还要更长,因为浅分页的偏移量比较小,而深分页大,所以深分页的扫描行数要比浅分页多,所以时间更长

3. 优化查询1

order by的排序字段添加索引

# 为order by的排序字段添加索引
ALTER TABLE student ADD INDEX idx_score (score);

浅分页:

# 浅分页
EXPLAIN
SELECT id, name, score from student order by score desc limit 5, 20;

执行效率:直接使用索引,额外执行Backward index scan

Backward index scan 是 MySQL8针对上面场景的一个专用优化项,它可以从索引的后面往前面读,性能上比加索引提示要好的多。在 MySQL 中我们创建的索引,默认索引的叶子节点是从小到大排序的,而此时我们查询排序时,是从大到小,所以,在扫描时,就是反向扫描,就会出现 Backward index scan 。

执行时间:0.032s,加快的查询时间

深分页:

  1. 执行默认方式

    执行效率:走的还是一个全表扫描

    执行时间:5.962s,和不使用索引差别不大

  2. 让深分页强制走索引:FORCE INDEX (idx_score)

EXPLAIN
SELECT id, name, score from student FORCE INDEX (idx_score) order by score desc limit 4500000, 20;

执行效率:和浅分页相同

执行时间:82.011s,查询时间大大增加

结论:

  1. 优点:浅分页查询速度得到很好的提升
  2. 缺点:深分页查询速度没有明显变化,如果走强制索引,查询时间还会大大增加

分析: 在使用索引后,索引需要做一个回表操作,这个需要时间,而排序也需要时间,在执行深分页的时候,偏移量大,造成回表成本增大,所以这时候mysql会帮我们做一个优化,两者之间选一个最优的

4. 优化查询2

order by和select字段添加联合索引

# 创建联合索引
ALTER TABLE student ADD INDEX idx_score_name_id (score, name, id);

深分页:

# 深分页
EXPLAIN
SELECT id, name, score from student order by score desc limit 4500000, 20;

执行效率:使用索引,并且使用了覆盖索引(Using index)

执行时间:1.117,这里查询时间也是加快的很多

优点:深分页查询速度得到明显提升

缺点:当新增一个查询字段时,索引就会失效

5. 优化查询3

删除联合索引,防止干扰

# 删除联合索引,防止干扰
drop index idx_score_name_id on student;

深分页:

EXPLAIN
SELECT t1.id, t1.name, t1.score from student t1 join
(select id from student order by score desc limit 4500000, 20) t2 on t1.id = t2.id;

执行效率:效执行里面的子查询,查询走的是索引,然后再从子查询中获取到的20条数据在进行查询,查询走的是PRIMARY

查询时间:1.054s

优点: 深查询得到明显提升

缺点: 当子查询结果集过多时不推荐使用

6. 优化查询4

先将所有数据排序好,先根据score进行降序排序,score相同的情况下再根据id进行降序排序,然后在取前20条数据,这里还得和前端配合,前端每次发送请求都携带最后一个的id值和score值

EXPLAIN
SELECT id, name, score from student
WHERE id < 10000000 AND score <= 100
ORDER BY score DESC LIMIT 20;

执行效率:type类型为range

执行时间:0.034s

执行下一页:获取上一页最后一个id值和score值

SELECT id, name, score from student
WHERE id < 4975166 AND score <= 99.9
ORDER BY score DESC LIMIT 20;

7. 总结

  1. 浅分页可以给order by字段添加索引
  2. 深分页可以给order by和select字段添加联合索引
  3. 通过手动回表,走联合索引
  4. 从业务方面思考,获取对应数据

MySQL百万级数据查询相关推荐

  1. php mysql百万级数据_php+mysql百万级数据怎么排序_PHP教程

    php+mysql百万级数据如何排序? php+mysql百万级数据分页.因涉及多表多条件联合查询.谁能帮忙优化下面的查询语句. if(empty($wheresql)){ $wheresql=&qu ...

  2. Mysql 百万级数据优化资料

    Mysql 百万级数据优化资料 一.我们可以且应该优化什么? 硬件 操作系统/软件库 SQL服务器(设置和查询) 应用编程接口(API) 应用程序 -------------------------- ...

  3. Mysql - 百万级数据查询优化笔记 (PHP Script) ②

    Mysql - 百万级数据查询优化笔记 (PHP Script) ② 说明:要处理的是在一个脚本中统计的年度账单,和上一篇的处理思路完全 不同,先把全量取出,再按字典形式拼接,10w条数据只需要668 ...

  4. mysql千万级数据查询select、插入insert慢 可能原因总结

    mysql千万级数据查询select.插入insert慢 可能原因总结 表连表查询 并 insert ,insert into -select -from- insert into T1(XX,XX) ...

  5. mysql百万级数据查询优化实践-从开始到开除

    在某个项目中,订单表每天会产生5-10万条记录. 先前对大数据查询没多少处理经验,碰到难以查动的统计数据通常是建一张表,定时统计一次.或者写存储过程,优化查询过程. 按照以往一贯思路,建表,加索引. ...

  6. php mysql百万级数据_PHP+MySQL百万级数据插入的优化

    插入分析 MySQL中插入一个记录需要的时间由下列因素组成,其中的数字表示大约比例: 连接:(3) 发送查询给服务器:(2) 分析查询:(2) 插入记录:(1x记录大小) 插入索引:(1x索引) 关闭 ...

  7. MySQL百万级数据大分页查询优化

    前言:在数据库开发过程中我们经常会使用分页,核心技术是使用用limit start, count分页语句进行数据的读取. 一.MySQL分页起点越大查询速度越慢 直接用limit start, cou ...

  8. MySQL百万级数据分页查询及优化

    点击蓝色"程序猿DD"关注我哟 加个"星标",不忘签到哦 来源:https://www.cnblogs.com/geningchao 关注我,回复口令获取可获取 ...

  9. MySQL 百万级数据量分页查询方法及其优化

    来源:http://sina.lt/gauW 方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N 适应场景: 适 ...

最新文章

  1. linux内核开机显示企鹅logo,批改linux内核kernel开机logo(小企鹅)
  2. 远程控制 vc++实现
  3. linux下的汇编环境搭建(nasm)
  4. PAT甲级1074 Reversing Linked List :[C++题解]反转链表,借用vector
  5. Transform.Rotate 旋转
  6. npoi 导入 winform excel_勤哲Excel服务器做影视制作企业管理系统 - 科技
  7. 不相关子查询的工作方式是_课题组工作|Nucleic Acids Research|基于表达密度谱的特征子空间分离及相关单细胞转录组分群新算法...
  8. php 检测网址是否有效
  9. Thinkphp查询数据转成layui的展示格式
  10. mysql定义语言_MySQL基础(一)--数据定义语言DDL
  11. 转:Secure CRT 中文乱码问题解决
  12. onbeforeunload事件在页面关闭或刷新时触发
  13. Web 全栈大会:万维网之父的数据主权革命
  14. CSS篇十六——盒子模型之边框
  15. 起始方位角怎么确定_起始方位角.PPT
  16. 用EXCEL制作“倒计时器
  17. python个性化推荐系统毕业设计_个性化推荐系统架构设计(一)
  18. 百度AI攻略:实现人体姿态判定打分
  19. 转载:[5GC]5G LAN标准解读
  20. 小白学Pytorch系列-- Torch API (5)

热门文章

  1. java常用代码荟萃
  2. 【力扣刷题】只出现一次的数字
  3. 【读书笔记】《生命册》- 李佩甫 - 2012年出版
  4. Python 爬虫 校花网
  5. 小球跳跃游戏——EasyX图形库应用——C++小游戏
  6. 511遇见易语言API模块线程挂起(SuspendThread)
  7. Donkey框架之一:概述
  8. My English Bloger. The My Chinese Bloger.
  9. AndroidStudio,Colors.xml颜色表,配中文注释
  10. python实现循环赛日程表问题的算法_循环赛日程表的分治算法实现实验报告gxl.doc...