1 准备表结构

CREATE TABLE `student`  (
`id` int NOT NULL AUTO_INCREMENT,
`user_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`score` decimal(10, 2) NULL DEFAULT NULL,
`create_time` datetime NULL DEFAULT NULL,
`update_time` datetime NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

2 需求

按照成绩降序排列,并查询字段 user_no,user_name,score,做一个带排序的分页查询

3 自动执行数据

delimiter $$
CREATE PROCEDURE BatchInsert ( IN initId INT, IN loop_counts INT)BEGIN
DECLARE Var INT;
DECLARE ID INT; SET Var = 0;
SET ID = initId;
SET autocommit = 0; WHILE Var < loop_counts DO
INSERT INTO `test`.`student` ( `user_no`, `user_name`, `score`, `create_time`, `update_time` )
VALUES
(
CONCAT( '学号', ID ),
CONCAT( '姓名', ID ),
FLOOR( 1 + RAND()* 100 ),
DATE_ADD( '2023-3-30 16:08:00', INTERVAL ROUND( RAND()* 1000+1 ) DAY ),
DATE_ADD( '2023-3-30 16:08:00', INTERVAL ROUND( RAND()* 1000+1 ) DAY )
);
SET ID = ID + 1;
SET Var = Var + 1; END WHILE;
COMMIT; END $$;
delimiter;
CALL BatchInsert(1,2000000)

4 需要分页的sql

SELECT user_no,user_name,score FROM student ORDER BY score DESC LIMIT 5,20 #浅分页
SELECT user_no,user_name,score FROM student ORDER BY score DESC LIMIT 80000,20 #深分页

5 分页执行计划

通过执行计划 expladin 看下执行效率:

  • 浅分页:

  • 深分页:

可以看出 type=all 都是走的全表扫描,并且都使用了额外的文件排序,现在记录一下执行时间:

浅分页:0.887s,深分页:1.427s

5.1 对排序字段添加索引

对 score 添加索引:alter table student add index idx_score(score)

浅分页:

耗时:0.021s

深分页:

耗时:1.475s

可以看出,虽然对排序字段加了索引,但是由于深分页偏移量太大,还是选择了走全表扫描 type=all。并额外使用了文件排序。

可以分析出,排序需要成本,回表也需要成本,浅分页由于偏移量小,回表成本低,所以执行效率有很大的提升,深分页偏移量大,回表成本太高了,所以需要降低深分页回表的成本。

5.2 建立联合索引

建立联合索引,就是为了消除回表带来的效率损耗。

alter table student add index idx_no_name_score(score,user_no,user_name)

浅分页:

耗时:0.024s

深分页:

耗时:0.047s

可以看到,使用联合索引已经可以解决了回表的问题,两者的执行效率也高了很多,但是这种做法有一个缺点,如果我们要查询出来的数据多了一个字段,就得重建联合索引,这样扩展性太差肯定不能接受的。所以还有一种办法,手动回表。

5.3 手动回表

手动回表的前提是对order by 字段添加了索引

浅分页:

SELECT
user_no,
user_name,
score
FROM
student s1
JOIN ( SELECT id FROM student ORDER BY score DESC LIMIT 5, 20 ) s2 ON s1.id = s2.id

执行计划:

id 大的先执行

耗时:0.021s

深分页:

SELECT
user_no,
user_name,
score
FROM
student s1
JOIN ( SELECT id FROM student ORDER BY score DESC LIMIT 80000, 20 ) s2 ON s1.id = s2.id

执行计划:

耗时:0.042s

6 总结

优化方式 浅分页索引Type 深分页索引Type 浅分页耗时 深分页耗时
All All 0.887s 1.427s
order by 字段加索引 index All 0.021s 1.475s
联合索引 index index 0.024s 0.047s
手动回表(order by字段加索引) index index 0.021s 0.042s

实战SQL优化(以MySQL深分页为例)的更多相关文章

  1. atitit。mssql sql server 转换mysql 及 分页sql ast的搭建

    atitit.mssql sql server 转换mysql  及 分页sql ast的搭建 1. 主要的的转换::函数的转换,分页的转换 1 2. 思路::mssql sql >>as ...

  2. mysql的慢查询实战+sql优化

    背景:使用A电脑安装mysql,B电脑通过xshell方式连接,数据内容我都已经创建好,现在我已正常的进入到mysql中 步骤1:设置慢查询日志的超时时间,先查看日志存放路径查询慢日志的地址,因为有慢 ...

  3. 查询效率提升10倍!3种优化方案,帮你解决MySQL深分页问题

    开发经常遇到分页查询的需求,但是当翻页过多的时候,就会产生深分页,导致查询效率急剧下降. 有没有什么办法,能解决深分页的问题呢? 本文总结了三种优化方案,查询效率直接提升10倍,一起学习一下. 1. ...

  4. 正确使用索引(sql优化),limit分页优化,执行计划,慢日志查询

    查看表相关命令 - 查看表结构   desc 表名- 查看生成表的SQL   show create table 表名- 查看索引   show index from  表名 使用索引和不使用索引 由 ...

  5. 【SQL优化】MySQL官网中可优化的层次结构

    正如上一篇中我翻译的那篇文章,关于MySQL数据库优化的宏观介绍,了解到了从大体上来讲,优化MySQL可以从3个角度来讲.那么这一篇文章,则从一个个优化点出发,统计出究竟有多少个地方我们可以来优化My ...

  6. SQL优化-大数据量分页优化

    百万数据量SQL,在进行分页查询时会出现性能问题,例如我们使用PageHelper时,由于分页查询时,PageHelper会拦截查询的语句会进行两个步骤 1.添加 select count(*)fro ...

  7. MySQL 千万数据库深分页查询优化,拒绝线上故障!

    文章首发在公众号(龙台的技术笔记),之后同步到博客园和个人网站:xiaomage.info 优化项目代码过程中发现一个千万级数据深分页问题,缘由是这样的 库里有一张耗材 MCS_PROD 表,通过同步 ...

  8. SQL优化---慢SQL优化

    于2023.3.17日重写,之前写的还是太八股文太烂了一点逻辑都没有,这次重新写了之后,感觉数据库优化还是很有必要的,之前觉得不必要是我年轻了. 一.如何定位慢SQL语句 1.通过慢查询日志查询已经执 ...

  9. 工作中遇到的99%SQL优化,这里都能给你解决方案

    前几篇文章介绍了mysql的底层数据结构和mysql优化的神器explain.后台有些朋友说小强只介绍概念,平时使用还是一脸懵,强烈要求小强来一篇实战sql优化,经过周末两天的整理和总结,sql优化实 ...

  10. mysql实战优化之一:sql优化

    1.选取最适用的字段属性 MySQL 可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快.因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得 ...

随机推荐

  1. 【课程汇总】Hello HarmonyOS系列课程,手把手带你零基础入门

    HarmonyOS是面向未来.面向全场景的新一代智能终端操作系统,为不同设备的智能化.互联与协同提供了统一的语言,给人们带来简洁.流畅.连续.安全可靠的全场景交互体验. 初识HarmonyOS的开发者 ...

  2. ASP.NET 部署常见问题及解决方案

    ASP.NET 部署部署过程中常见问题及解决方案 Could not load file or assembly 'XXXXX' or one of its dependencies. Access ...

  3. c# .net缓存(旧)

    前言 是迁移以前的blog. 关于c# 缓存在web应用中的一个引导,能够建立起一个缓存的基本思路. System.Web.Caching 这个真的是老生常谈了,我们只需要key和iv,然后我们就可以 ...

  4. Caused by: org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration$ArtifactResolveException: Could not resolve all files for configuration ':classpath'.

    前言 这个错误怎么看呢? 如果你对gradle 不是很了解的话,有一个建议,就是把异常背下来,当然是看这个:ArtifactResolveException哈. 而不是后面的详情. 正文 给我们详情是 ...

  5. 使用 Docker 部署 instantbox 轻量级 Linux 系统

    1)instantbox 介绍 GitHub:https://github.com/instantbox/instantbox instantbox 是一款非常实用的项目,它能够让你在几秒内启动一个主 ...

  6. mac版本vscode窗口崩溃crashed

    1.截图 出现时机 当安装依赖的时候大概率会出现,甚至安装一次依赖会出现几次 解决 具体原因未知 重新启动电脑以及退出软件都不能解决 去官网重新下载,重新安装问题解决

  7. 硬之城携手阿里云 Serverless 应用引擎(SAE)打造低代码平台

    简介: 简化用云的成本,把复杂留给自己,简单留给用户. 作者 | 陈泽涛(硬之城产品总监)& 洛浩(阿里云云原生高级架构师) 硬之城成立于 2015 年,是一家以电子元器件 BOM 整体供应为 ...

  8. E百科 | 第2期 扒一扒能加速互联网的QUIC协议

    简介: 众所周知,QUIC(Quick UDP Internet Connection)是谷歌制定的一种互联网传输层协议,它基于UDP传输层协议,同时兼具TCP.TLS.HTTP/2等协议的可靠性与安 ...

  9. 如何通过Graph+AI的方法打造高精度风控模型

    简介: 阿里云图智能平台在金融行业已经帮助银行.保险等领域客户构建了金融风控.商品推荐.循环担保检测.异常指标监控.违规团伙挖掘等场景,通过穿透行业应用场景,帮助客户基于多维数据做出精准决策. > ...

  10. [GPT] 机器学习框架平台或框架的学习成本和友好程度排名?

      按照学习成本从高到低的顺序,大概如下: TensorFlow:虽然TensorFlow功能强大,但学习曲线比较陡峭,需要掌握一些深度学习的基本概念和数学知识. PyTorch:PyTorch相对而 ...