MySQL 分页查询越往后翻越慢的原因

MySQL 分页查询越往后翻越慢的原因

在实际开发场景中,分页查询(如通过LIMITOFFSET)越往后翻越慢的问题通常是由于以下原因造成的:

  1. 全表扫描

    • MySQL在处理带有OFFSET的查询时,需要先扫描到OFFSET指定的行数,然后再返回结果集。随着OFFSET的增加,MySQL需要扫描更多的行才能找到目标数据。
    • 示例:假设有一个包含百万条记录的订单表,执行以下查询:
      SELECT * FROM orders ORDER BY created_at DESC LIMIT 10 OFFSET 100000;
      
      这个查询需要先扫描前100,000行,然后再返回接下来的10行,导致性能显著下降。
  2. 内存消耗

    • OFFSET很大时,MySQL需要将这些行暂存在内存中,然后再过滤掉前面的行,只返回后面的行。这会消耗大量内存,并降低查询速度。

优化策略

在实际开发中,可以采用以下策略来优化分页查询:

1. 使用覆盖索引(Covering Index)

覆盖索引是指索引包含了查询所需的所有字段,因此MySQL可以直接从索引中获取数据,而不需要回表。这样可以显著减少I/O操作。

  • 示例:假设有一个订单表orders,我们需要按时间倒序分页查询订单。可以为orders表创建一个复合索引:
    CREATE INDEX idx_orders_created_at ON orders(created_at, id);
    
    然后查询时只选择索引覆盖的字段:
    SELECT id, created_at FROM orders ORDER BY created_at DESC LIMIT 10 OFFSET 100000;
    
    这样MySQL可以直接从索引中获取数据,而不需要回表。
2. 使用子查询优化分页

通过子查询先获取OFFSET对应的id,然后再根据这些id进行查询。这样只需要扫描目标区间,而不是全表。

  • 示例:假设我们需要按订单创建时间倒序分页查询订单,可以通过子查询优化:
    SELECT * FROM orders WHERE id > (SELECT id FROM orders ORDER BY created_at DESC LIMIT 1 OFFSET 100000
    ) ORDER BY created_at DESC LIMIT 10;
    
    这个查询先通过子查询找到第100,001条记录的id,然后再从该id开始查询10条记录。
3. 使用游标实现分页

在一些前后端分离的应用中,可以通过游标(Cursor)在应用程序中实现分页,而不是依赖数据库的分页机制。每次查询时,记住当前的最大id,然后在下次查询时从该id开始。

  • 示例(Python语言):
    last_id = None
    while True:query = "SELECT * FROM orders"if last_id:query += " WHERE id > %s"query += " ORDER BY created_at DESC LIMIT 10"result = execute_query(query, last_id)if not result:breaklast_id = result[-1]['id']process(result)  # 处理查询结果
    
    这种方法可以避免OFFSET带来的性能问题。
4. 使用延迟关联(Late Materialization)

延迟关联是指先通过覆盖索引查询出主键,然后再通过主键回表查询实际数据。这样可以减少回表次数,提高查询效率。

  • 示例:假设我们需要按订单创建时间倒序分页查询订单,可以通过延迟关联优化:
    SELECT o.* 
    FROM orders o
    INNER JOIN (SELECT id FROM orders ORDER BY created_at DESC LIMIT 10 OFFSET 100000
    ) AS tmp ON o.id = tmp.id;
    
    这个查询先通过子查询找到第100,000条记录的id,然后再根据这些id回表查询实际数据。
5. 合理设计数据分片

在高并发场景下,可以考虑将大数据表水平分片,减少单个表的行数,从而提高查询效率。

  • 示例:假设订单表数据量极大,可以将订单按月分表,例如orders_2023_01orders_2023_02等。在查询时可以根据时间范围选择对应的表:
    SELECT * FROM orders_2023_10 ORDER BY created_at DESC LIMIT 10 OFFSET 100000;
    
    这种方式可以显著减少单表的行数,提高分页查询的效率。

总结

在实际开发中,分页查询越往后翻越慢的主要原因是OFFSET导致了全表扫描和内存消耗。通过使用覆盖索引、子查询、游标、延迟关联以及合理分片等优化策略,可以显著减少扫描行数,提高分页查询的性能。在选择优化策略时,需要根据具体的业务场景和数据规模来决定。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity编辑器 连接不到SteamVR问题记录

问题表现:之前正常的工程,某天打开后运行,在SteamVR未打开时,Unity工程运行后无法调用起来Steam VR,无任何反应,但用其他软件则可以调用起来SteamVR,并且运行正常,在重装了XR的一些插…

nfs作业

nfs作业 服务机: 编写配置文件: [rootlocalhost ~]# vim /etc/exports 配置文件内容: /nfs/shared *(ro,sync) /nfs/upload 192.168.36.0/24(rw,anonuid210,anongid210,sync) /home/tom 192.168.36.132(rw) 创建目录,文件&am…

qt QMainWindow详解

一、概述 QMainWindow继承自QWidget,并提供了一个预定义的布局,将窗口分成了菜单栏、工具栏、状态栏和中央部件区域。这些区域共同构成了一个功能丰富的主窗口,使得应用程序的开发更加简单和高效。 二、QMainWindow的常用组件及功能 菜单栏&…

Leetcode11:盛水最多的容器

原题地址:. - 力扣(LeetCode) 题目描述: 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳…

【每日一题】LeetCode - 判断回文数

今天我们来看一道经典的回文数题目,给定一个整数 x ,判断它是否是回文整数。如果 x 是一个回文数,则返回 true,否则返回 false。 回文数 是指从左往右读和从右往左读都相同的整数。例如,121 是回文,而 123 …

Maven 项目管理工具

目录 Maven简介 Maven快速上手 Maven详细介绍 Maven工作机制 Maven安装及配置 使用IDEA创建Maven Web工程 Maven简介 Maven是 Apache 开源组织奉献的一个开源项目,可以翻译为“专家”或“内行”。 Maven 的本质是一个项目管理工具,将项目开发和管…

Tangible Software Solutions 出品最准确可靠的源代码转换器

Tangible Software Solutions 出品最准确可靠的源代码转换器 简介1、Instant C#(VB.NET to C#)2、Instant VB(C# to VB.NET)3、C to C# Converter4、C to Java Converter5、C to Python Converter6、Java to C# Converter7、Java to C Converter8、Java to Python Converter9、…

首届The VRAnimation Award 震撼启幕!VsoCloud独家赞助此次大赛!

CG行业的精英与爱好者们,你们的舞台已经搭好!备受瞩目的首届The VR & Animation Award现已正式拉开帷幕,诚邀各位共襄盛举!丰厚大奖、作品曝光、行业资源分享……多重惊喜等你来解锁! 此次大赛由Rival Technologie…

生产工单系统如何帮助企业控制成本?

我们都知道,在现在竞争日益激烈的市场环境中,企业对于成本控制的需求达到了前所未有的高度。每一分成本的优化,都直接关系到企业的盈利能力和市场竞争力。成本贯穿于生产、销售、管理等各个环节。其中,生产环节的成本控制更是关键…

【瑞吉外卖】-day01

目录 前言 第一天项目启动 获取资料 创建项目 ​编辑 连接本地数据库 连接数据库 修改用户名和密码 ​编辑创建表 创建启动类来进行测试 导入前端页面 创建项目所需目录 检查登录功能 登录界面 登录成功 登录失败 代码 退出功能 易错点 前言 尝试一下企业级项…

2024.10.25 软考学习笔记(知识点)

刷题网站: 软考中级软件设计师在线试题、软考解析及答案-51CTO题库-软考在线做题备考工具

map 和 set 的使用

文章目录 一.序列式容器和关联式容器二. set 系列的使用1. set 和 multiset 参考文档2. set 类介绍3. set 的构造和迭代器4. set 的增删查5. insert 和迭代器遍历使用样例6. find 和 erase 使用样例7. multiset 和 set 的差异 三. map 系列的使用1. map 和 multimap参考文档2. …

【Spring】Spring Boot 日志(8)

本系列共涉及4个框架:Sping,SpringBoot,Spring MVC,Mybatis。 博客涉及框架的重要知识点,根据序号学习即可。 1、日志概述 1.1学习日志的必要性 在第一次学习编程语言的时候,我们就在使用printf或者System.out.println等打印语句打印日志了…

Python超轻量对话框:easyGUI

文章目录 简介box回调函数 简介 EasyGUI是一个非常简单的GUI模块,提供了许多对话框,所有交互操作都通过简单的函数调用实现。支持pip安装,十分便捷 pip install easygui通过一行代码,即可实现下面的对话框 其对应的代码为 impo…

ArrayList和Array、LinkedList、Vector 间的区别

一、ArrayList 和 Array 的区别 ArrayList 内部基于动态数组实现,比 Array(静态数组) 使用起来更加灵活: ArrayList 会根据实际存储的元素动态地扩容或缩容,而 Array 被创建之后就不能改变它的长度了。ArrayList 允许…

雷池社区版OPEN API使用教程

OPEN API使用教程 新版本接口支持API Token鉴权 接口文档官方没有提供,有需要可以自行爬取,爬了几个,其实也很方便 使用条件 需要使用默认的 admin 用户登录才可见此功能版本需要 > 6.6.0 使用方法 1.在系统管理创建API TOKEN 2.发…

OpenGMS是什么?如何使用OpenGMS的建模与模拟工具(一)

目录 OpenGMS是什么?如何使用OpenGMS的建模与模拟工具(一) 一、什么是OpenGMS 1、OpenGMS网站 2、OpenGMS团队 二、为什么我们需要OpenGMS 1、地理模拟实验的局限性区域性限制了科研应用的效率 2、外界对于OpenGMS的评价 三、 OpenG…

springboot095学生宿舍信息的系统--论文pf(论文+源码)_kaic

学生宿舍信息管理系统 摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了学生宿舍信息管理系统的开发全过程。通过分析学生宿舍信息管理系统管理的不足,创建了一个计算机管理学生宿舍信息管理系统的方…

五、大模型(LLMs)RAG检索增强生成面

本文精心汇总了多家顶尖互联网公司在大模型RAG检索增强生成考核中的核心考点,并针对这些考点提供了详尽的解答。并提供电子版本,见于文末百度云盘链接中,供读者查阅。 5.1 大模型(LLMs)RAG 入门篇 基于LLM向量库的文档…

VGG16

1️⃣ VGG介绍 Alexnet证明了神经网络变深是有效的,因此网络能不能更深更大?   VGG(visual geometry group)是由牛津大学提出的使用“块思想”的网络,通过使用循环和子程序可以很容易地在任何现代深度学习框架的代码…