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

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 这个分区表,而不需要访问其他分区表,提高了查询效率。

相关文章:

  • 架构师论文《论模型驱动架构软件开发方法及其应用》
  • 【软件测试】性能测试 —— 工具篇 LoadRunner 介绍与使用
  • Ansible模块——服务管理和设置定时任务
  • 一字典两世界:优雅移除 `NSDictionary` 指定键的最佳实践
  • 腾讯 CodeBuddy 杀入 AI 编程赛道,能否撼动海外工具霸主地位?
  • C++类与对象--2 对象的初始化和清理
  • tp5 关键词搜索商品时进行关键词拆分
  • [Linux]我在Linux世界觉醒了指令系统
  • JavaScript基础-创建对象的三种方式
  • 【C++重载操作符与转换】文本查询示例
  • 数据库故障排查指南:解决常见问题,保障数据安全与稳定
  • 数据分析_Python
  • PyTorch实现三元组损失Triplet Loss
  • 为什么 Docker 建议关闭 Swap
  • 基于多头自注意力机制(MHSA)增强的YOLOv11主干网络—面向高精度目标检测的结构创新与性能优化
  • Elasticsearch Fetch阶段面试题
  • Springboot构建项目时lombok不生效
  • 51单片机仿真突然出问题
  • Almalinux中出现ens33 ethernet 未托管 -- lo loopback 未托管 --如何处理:
  • 提示词定制-AI写方案太泛?用“5W1H”提问法,细节拉满!
  • 关税影响下沃尔玛想涨价,特朗普施压:自行承担,别转嫁给顾客
  • 法律顾问被控配合他人诈骗酒店资产一审判8年,二审辩称无罪
  • 湖南慈利一村干部用AI生成通知并擅自发布,乡纪委立案
  • 自强!助残!全国200个集体和260名个人受到表彰
  • 标普500指数连涨四日,大型科技股多数下跌
  • 呼吸医学专家杜晓华博士逝世,终年50岁