当前位置: 首页 > backend >正文

mysql中limit深度分页详细剖析【爽文】

目录

一 mysql中limit深度分页

1.1 背景描述

1.2 mysql深度分页很慢原因

1.2.1 mysql的sql执行流程

1.2.2 mysql的深度分页很慢原因

1.3 解决办法

1.3.1 覆盖索引

1.3.2 子查询

1.3.3 标签查询

1.3.4 分区表


一 mysql中limit深度分页

1.1 背景描述

Limit深度分页造成慢sql,导致系统数据库cpu高负载,使用率爆满,其他业务的数据库请求无法得到及时响应。造成接口超时,最后,拖垮主服务器

语法:select * from  t limit m,n

分页查询时,我们会在LIMIT后面传两个参数,一个是偏移量(offset),一个是获取的条数(rows)。LIMIT分页查询的时间与偏移量值成正比。当偏移量越大时,查询时间越长。

偏移量

耗时

10w

61

100w

273

对于普通的业务而言,超过1秒的查询是绝对不可以忍受的。

1.2 mysql深度分页很慢原因

1.2.1 mysql的sql执行流程

mysql服务端架构包括两层,server层和存储引擎层

1)server层:查询缓存,解析sql语句生成语法树,执行sql。

在执行sql中包括预处理器,优化器和执行器。

预处理器:将查询字段展开(如select * 展开为具体字段)并检查字段是否合法

优化器:指定sql执行计划,如选择合适的索引

执行器:与存储引擎层交互,执行sql语句

2)Engine层:存储引擎层 如InnoDB和MyISAM。

以InnoDB为例,访问B+树数据结构获取记录(聚簇索引,二级索引等的访问都在存储引擎层)

3)归结:对于limit m,n,则在引擎层返回m+n条数据,server层丢弃m条,返回n条数据给客户端。

1.2.2 mysql的深度分页很慢原因

mysql服务端架构包括两层,server层和存储引擎层

对于limit m,n,则在引擎层返回m+n条数据,server层丢弃m条,返回n条数据给客户端。https://mp.weixin.qq.com/s/LXvQMQFf_SyLWh1zI6onkA

当 Limit 抛弃的数据量太大的时候,server层的优化器认为索引扫描 的效率,甚至不如【全表扫描 +文件排序filesort】,于是将索引扫描优化为【全表扫描】。而一个大表的全表扫描,本身就是很慢的。

1.3 解决办法

1.3.1 覆盖索引

将查询的字段作为索引的子集或者全集;使用覆盖索引可以直接查询索引页,不必查找数据页;减少I/O次数,提高查询效率。

在val和name中加联合索引;如下,走覆盖索引

select val,name  from test where val=4 limit 300000,5;

1.3.2 子查询

如果不能使用索引覆盖扫描,或者查询字段较多,可以尝试使用子查询。

先用子查询将需要查询的内容的id找到,然后主查询通过这些id,查询出需要的完整信息。

select * from test where id in (select id from test where val=5 limit 200000,10);

这样,Mysql 先执行子查询,在 val 索引上进行范围扫描,并返回 10个 id 值。然后,Mysql 再执行主查询,在 id 索引上进行点查找,并返回所有字段。这样,Mysql 只需要扫描10个数据页,而不是200010个数据页,提高了查询效率。

1.3.3 标签查询

使用这种方式,表中必须有连续自增id的情况下才能使用。上一次查询的最后一条的数据id,代入本次查询,作为起始位置,进行pagesize翻页。这样的话,后面无论翻多少页,性能都会不错的,因为命中了id索引。但是这种方式有局限性:需要一种类似连续自增的字段

select  id,name,balance FROM account where id > 100000 limit 10;

1.3.4 分区表

如果表中数据分布不均匀,将表进行分区,查询时候查询某个范围的区域,而不是整个表中数据,则可以提高查询效率。

如果按照 val 字段将 test 表分成 10 个分区表(test_1 到 test_10),每个分区表只存储 val 等于某个值的记录,可以执行以下语句:

select * from test_4 limit 300000,5;

这样,Mysql 只需要访问 test_4 这个分区表,而不需要访问其他分区表,提高了查询效率。

http://www.xdnf.cn/news/6839.html

相关文章:

  • 黑马点评-用户登录
  • 边缘计算:物联网的“加速器”与“守护者”
  • CentOS 上配置 Docker 使用 NVIDIA GPU
  • 【论文阅读】人脸修复(face restoration ) 不同先验代表算法整理2
  • Python标准库完全指南:os、sys与math模块详解与实战应用
  • DeepSeek指令微调与强化学习对齐:从SFT到RLHF
  • 【MySQL进阶】如何在ubuntu下安装MySQL数据库
  • React中useState中更新是同步的还是异步的?
  • 配置git从公网能访问-基于frp
  • Oracle 的 ASSM 表空间
  • 【论文阅读】人脸修复(face restoration ) 不同先验代表算法整理
  • 06、基础入门-SpringBoot-依赖管理特性
  • Linux之Nginx安装及配置原理篇(一)
  • 设计模式 - 单例模式 - Tips
  • 面试真题 - 高并发场景下Nginx如何优化
  • 开源安全大模型Foundation-Sec-8B实操
  • C语言_动态内存管理
  • 18.自动化生成知识图谱的多维度质量评估方法论
  • (9)python开发经验
  • NDS3211HV单路H.264/HEVC/HD视频编码器
  • math toolkit for real-time development读书笔记一三角函数快速计算(1)
  • Guided Filtering相关记录
  • 牛客网NC22222:超半的数
  • 登高架设作业人员的职业发展方向有哪些?
  • Lazada测评补单系统搭建指南:从环境到账号的要点把控
  • 深入解析Shell脚本编程:从基础到实战的全面指南
  • L52.【LeetCode题解】二分法习题集1
  • BigemapPro小技巧:如何只显示特定区域内的点
  • Linux 内核版本详解
  • 数据中心末端配电监控产品