Mysql大数据量分页优化

news2025/1/16 21:07:01

前言

之前有看过到mysql大数据量分页情况下性能会很差,但是没有探究过它的原因,今天讲一讲mysql大数据量下偏移量很大,性能很差的问题,并附上解决方式。

原因

将原因前我们先做一个试验,我做试验使用的是mysql5.7.24版本(mysql8上我也试验出来同样的问题),看看mysql是不是在偏移量比较大的时候分页会比较慢,性能比较差

版本

mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.24    |
+-----------+
1 row in set (0.00 sec)

表结构

CREATE TABLE `trace_monitor_log` (
  `id` varchar(30) NOT NULL COMMENT '表主键id',
  `user_id` varchar(30) DEFAULT NULL COMMENT '用户id',
  `trace_id` varchar(30) DEFAULT NULL COMMENT '追踪id',
  `trace_type` varchar(30) DEFAULT NULL COMMENT '追踪类型',
  `path` mediumtext COMMENT '追踪路径',
  `source_ip` varchar(255) DEFAULT NULL COMMENT '来源ip',
  `ext_params` mediumtext COMMENT '请求扩展参数',
  `costs` int(11) DEFAULT '0' COMMENT '请求耗时(毫秒)',
  `exception` mediumtext COMMENT '异常信息',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  KEY `trace_id` (`trace_id`),
  KEY `trace_type` (`trace_type`),
  KEY `create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='监控日志表';

试验过程

这个是我从测试环境找的一张日志表,里面的数据量是580万左右,我们先看看只查询普通10条数据的情况。

数据量

mysql> select count(*) from trace_monitor_log;
+----------+
| count(*) |
+----------+
|  5806836 |
+----------+
1 row in set (1.66 sec)
explain select * from trace_monitor_log order by trace_id limit 10;

image-20240128210052009

可以看到没有offset偏移量的时候可以直接走索引,key是trace_id,并且只查询了10条数据。

我们在来看看如果offset是1000的时候。

explain select * from trace_monitor_log order by trace_id limit 10 offset 1000;

image-20240128210345205

可以看到偏移量比较小的时候还是可以走索引,rows是1010,这时候发现虽然我们只要查询10条数据,但是查询的时候还是会扫描1000条无用的索引记录。

我们接下往下把offset加到100万

explain select * from trace_monitor_log order by trace_id limit 10 offset 1000000;

image-20240128210656849

这个时候就会发现一个神奇的现象,竟然没有走索引了,type是ALL,就是全表扫描了,执行时间大概花了40多秒,性能确实很差。这里的原因,本来根据索引查出来100万条记录,然后把不需要的数据给丢弃掉,mysql会计算查询成本,发现这样走索引还没有全表扫描快,所以用了全表扫描,但是全表扫描就为了拿到十条数据显然是性能很差的。mysql并不会自动判断先根据trace_id的索引找到偏移量需要的10条数据,再根据这10条索引找到叶子节点的主键记录去回表查询数据,导致了这么差的性能。

解决方式

1.延迟关联

先使用覆盖索引的方式找到对应order by 之后的limit条索引,因为是覆盖索引,直接用的索引记录,没有回表所以很快。接着在使用join的方式,将索引记录和原表关联起来就可以查出来对应的limit条数据。

explain select * from trace_monitor_log t1 join (select trace_id from trace_monitor_log  order by trace_id limit 1000000,10) t2 on t1.trace_id = t2.trace_id

image-20240128211946406

image-20240128212044859

执行时间平均在500-600毫秒左右,相比全表扫描快了很多。

2.书签记录

这个概念我也是从网上看到的,还没找到具体这个概念的出处在哪里。不过不要困于这个概念,只要理解是先找到对应要查询一条索引记录(书签),再根据这个索引去范围查询对应的limit条数数据就容易理解了。

explain select * from trace_monitor_log t1 where trace_id > (select trace_id from trace_monitor_log  order by trace_id limit 999999,1)   order by trace_id limit 10

image-20240128212614389

image-20240128213228356

执行时间和延迟关联差不多,也都走了索引,所以性能也比较好。

参考资料

1.mysql8官网limit优化

2.要想通过面试,MySQL的Limit子句底层原理你不可不知

3.从官方文档中探索MySQL分页的几种方式及分页优化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1416724.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Blender教程(基础)-物体的移动、旋转与缩放-04

一、新建一个立方体 ShiftA新建一个立方体用来演示。 二、物体的移动 xyz轴移动 点击下图图左侧的移动选项后,选中要移动的物体,会出现三个箭头的方向,这分别代表沿着x、y、z轴移动。xyz平面移动 这个小正方体代表沿着某一个面移动&#…

范仲淹大直男逆袭,先天下之忧而忧

人在最艰苦时,最能体现英雄本色。 天底下最苦的是读书。读书要眼到、手到、心到,专心致志,灵活运用。 范仲淹读书很用功,每天煮一锅粥。等到第二天,粥凝固了,范仲淹把隔夜粥划为四块,早上吃两块…

【c语言】详解操作符(上)

1. 操作符的分类 2. 原码、反码、补码 整数的2进制表示方法有三种,即原码、反码、补码 有符号整数的三种表示方法均有符号位和数值位两部分,2进制序列中,最高位的1位是被当做符号位其余都是数值位。 符号位都是用0表示“正”,用…

【Web】专栏文章索引

为了方便 快速定位 和 便于文章间的相互引用等 作为一个快速准确的导航工具 Linux 目录: (一)云服务器的购买与使用

P2246 SAC#1 - Hello World(升级版)

网址如下: P2246 SAC#1 - Hello World(升级版) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 刚开始是用递归做的,虽然用了哈希表优化,但是超时,只得了50 后面想到了一个新的算法,时间复杂度…

Steam游戏免费玩 gamebox 一起来玩幻兽帕鲁吧

steam大作免费畅玩 幻兽帕鲁也有资源 UI设计精美 还有补票链接,点击一下,就能跳转至Steam商店 可以自定义安装位置 下载链接 gamebox:https://rssm666.lanzn.com/b039g6dqj

数据结构排序小结

排序类型小结 💦 插入排序直接插入排序希尔排序 💦 选择排序直接选择排序堆排序 💦 交换排序冒泡排序快速排序🐾霍尔版本补坑位版本前后指针版本非递归版本 💦 归并排序递归版本非递归版本 💦 性能测试 &am…

Ps:根据 HSB 调色(以可选颜色命令为例)

在数字色彩中,RGB 和 HSV(又称 HSB)是两种常用的颜色表示方式(颜色模型)。 在 RGB 颜色模式下,Photoshop 的红(Red)、绿(Green)、蓝(Blue&#xf…

韦东山嵌入式Liunx入门笔记一

文章目录 一、嵌入式Linux二、Ubuntu系统2-1 安装软件2-2 Linux文件(1) 文件架构(2)文件属性(3)文件命令(4) 解压、压缩文件(5) 网络命令 2-3 vi编辑器2-4 Ubuntu下包管理 三、配置网卡四、安装后续学习使用的软件4-1 MobaXterm4-2 FileZilla4-3 Source Insight4.04-4 下载BSP4…

sqli-labs-master 下载、搭建

sqli-labs-master sqli-labs-master 是一个帮助用户学习和测试 SQL 注入漏洞的开源项目。它提供了一系列的环境,用户可以在这些环境中进行实验,学习如何检测、利用和防御 SQL 注入攻击。 sqli-labs 下载地址: github.com/Audi-1/sqli-labs 搭…

刘知远团队大模型技术与交叉应用L5-BMSystem

为什么需要BMTrain? PLM越来越大。为了使训练更高效和廉价。我们有必要 1.分析GPU的显存去哪了? 2.理解GPU间的合作模式是如何的? 显存都去了哪里? CPU vs GPU CPU适合复杂逻辑运算。GPU适合大量重复的数值运算。 显存成分 1.前…

【Java】SpringMVC参数接收(二):JSON、URI、文件

1、获取JSON参数 RequestMapping("/hello") RestController public class HelloSpring {RequestMapping("/t10")public String t10(RequestBody UserInfo userInfo){return userInfo.toString();} } 2、获取URI中的参数 (1)获取单…

面对.pings勒索病毒威胁:深度解析如何对抗.pings勒索病毒的危害

导言: 随着科技的发展,互联网的普及,网络犯罪也在不断演变。其中一种恶意软件,.pings勒索病毒,威胁着个人和企业的数据安全。本文91数据恢复将介绍.pings勒索病毒的特点、如何恢复被加密的数据文件,以及有…

Codeforces Round 921 (Div. 2)

Codeforces Round 921 (Div. 2) Codeforces Round 921 (Div. 2) A. We Got Everything Covered! 题意:找到一个字符串s,使得所有可能长度为n的字符串都可以用前k个小写字母组成,并为s的子序列。 思路:A的题意理解对C很有用 首…

Leetcode 206 反转链表

反转链表 准备工作1)ListNode基本结构2)初始化ListNode集合 解法一:遍历创建新节点解法二:两组List,面向对象操作解法三:递归调用解法四:直接移动解法五:解法二的面向过程 Leetcode …

Java异常处理集合

Java异常处理 Java语言在执行后会中断,也就是在出错位置后的代码都不会被执行,为了使非致命错误后的程序仍然能够执行,引入异常处理机制。 异常 可处理的异常用Exception表示,不可处理的异常用Error表示,通常是栈内…

ShardingSphere之ShardingJDBC客户端分库分表下

目录 ShardingJDBC实战 STANDARD标准分片策略 COMPLEX_INLINE复杂分片策略 CLASS_BASED自定义分片策略 HINT_INLINE强制分片策略 ShardingJDBC实战 上篇已经将需要用到的类、数据库表都准备好了,本篇主要介绍分片配置文件。 STANDARD标准分片策略 如果按照上篇文…

Python笔记14-实战小游戏飞机大战(上)

文章目录 功能规划安装pygame绘制游戏窗口添加玩家飞机图像屏幕上绘制飞船代码重构驾驶飞船全屏模式射击 功能规划 玩家控制一艘最初出现在屏幕底部中央的飞船。玩家可以使用箭头键左右移动飞船,还可使用空格键射击。游戏开始时,一群外星人出现在天空中…

如何从 Android SD 卡恢复已删除的照片

您是否不小心从 Android SD 卡中删除了一些照片?您是否尝试访问昨天拍摄的照片,但无论您在哪里查看都找不到它们?您的 Android 手机的外部存储是否已损坏,其内容无法访问? 在这种情况下,您应该尽快采取行动…

LV老板重夺全球首富 再次超过马斯克;新东方安徽总部大厦启用;中国与泰国签署互免签证协定

今日精选 • LV老板重夺全球首富 再次超过马斯克• 新东方安徽总部大厦启用• 中国与泰国签署互免签证协定 投融资与企业动态 • ​​传Temu将于3月在美国上线半托管业务• 国内数字支付解决方案提供商 “连连数字” 估值150亿,即将IPO• 滴滴与宁德时代宣布成立…