Mysql 深度分页查询优化

Mysql 分页优化

1. 问题根源

问题: mysql在数据量大的时候,深度分页数据偏移量会增大,导致查询效率越来越低。
问题根源:
当使用 LIMIT 和 OFFSET 进行分页时,MySQL 必须扫描 OFFSET + LIMIT 行,然后丢弃前 OFFSET 行。这意味着随着分页的深入,MySQL 需要扫描的行数会越来越多,导致查询性能下降。

例如,以下查询用于获取第 10001 到第 10010 行的数据:

SELECT * FROM table_name ORDER BY age LIMIT 10 OFFSET 10000;

在这种情况下,MySQL 必须扫描 10010 行,即使只返回 10 行。这种扫描和丢弃操作会导致大量的 I/O 操作,特别是在表数据量很大的情况下。

2. 优化方案

此问题整理出3个有效的优化方案。

2.1 方案1:索引优化

确保在用于排序和过滤的列上创建适当的索引,索引可以显著减少 MySQL 需要扫描的行数。

例如,如果 where 查询语句中包含 id 列排序,确保 id 列是索引列。否则的话,可能 MySQL 会扫描所有行,从而导致性能下降。


SELECT * FROM table_name ORDER BY id LIMIT 10 OFFSET 10000;

使用索引优化查询这种方法通过避免使用 OFFSET,减少了不必要的行扫描。

2.2 方案2:使用覆盖索引

使用联合索引,查询结果集为联合索引的列,可以提高深分页的查询效率;(但是不适用于频繁的增加查询字段的业务场景,因为需要联合索引也需要进行添加,否则添加的查询字段会进行回表,会增加执行时间)


-- 创建一个column1, column2的组合索引
CREATE INDEX idx_cover ON table_name (column1, column2);

-- 使用覆盖索引查询column1, column2
SELECT column1, column2 FROM table_name WHERE column1 = ? AND column2 = ?;

上面的示例中,查询只需从索引中获取数据,而不需要访问表的数据页,因此可以避免回表操作,从而提升性能。

2.3. 方案3:手动回表

针对优化方案2中在新增字段后,回表问题。方案3提出手动回表,提高执行效率。使用子查询查询出id的结果集,根据id手动回表查询,其他非索引字段,通过减少数据偏移量优化。(但是不适用与子查询中结果集过大,也会导致查询效率低)

2.4. 方案4:标记

结果业务场景,进行范围查询,需要前端配合,在翻页的时候将范围查询的最后一项参数传入后端
或者标记分页,通过保存上一次查询的最后一个记录的标记(通常是唯一标识符)来实现的,这种方法不使用 OFFSET,而是使用** WHERE **子句来获取下一页的数据:


SELECT * FROM table_name
WHERE id > last_id
ORDER BY id
LIMIT 20;

这种方法尤其适用于有序的、连续的分页请求。

2.5. 方案5:分区表

如果数据集非常大,可以考虑使用表分区。分区可以将表分成更小的块,从而减少每次查询需要扫描的数据量。MySQL 支持多种分区方法,如范围分区、列表分区等。

如下示例:假设有一个包含销售记录的表 sales,其中有一列 sale_date,表示销售的日期。我们希望按年份对这个表进行分区,以便更高效地进行查询。

2.5.1 创建表并按范围分区

CREATE TABLE sales (
    sale_id INT PRIMARY KEY,
    product_id INT,
    quantity INT,
    sale_date DATE
)
PARTITION BY RANGE (YEAR(sale_date)) (
    PARTITION p2021 VALUES LESS THAN (2022),
    PARTITION p2022 VALUES LESS THAN (2023),
    PARTITION p2023 VALUES LESS THAN (2024)
);

在这个示例中,sales 表被分成三个分区:

  • p2021 包含所有 sale_date 在 2021 年的记录。
  • p2022 包含所有 sale_date 在 2022 年的记录。
  • p2023 包含所有 sale_date 在 2023 年的记录。

每个分区都是独立的物理存储单元,因此查询可以只访问相关的分区。

2.5.2 插入数据

当插入数据时,MySQL 会根据 sale_date 自动将记录放入相应的分区。


INSERT INTO sales (sale_id, product_id, quantity, sale_date) VALUES
(1, 101, 5, '2021-06-15'),
(2, 102, 10, '2022-07-20'),
(3, 103, 8, '2023-03-10');

2.5.3 查询分区表

查询分区表时,MySQL 会自动确定需要访问哪些分区。例如:


SELECT * FROM sales WHERE sale_date BETWEEN '2022-01-01' AND '2022-12-31';

在这个查询中,MySQL 只会访问 p2022 分区,从而提高查询性能。

2.5.4 其他分区类型

除了范围分区(RANGE),MySQL 还支持其他几种分区类型,包括:

  • 列表分区(LIST):根据离散值列表进行分区。
  • 哈希分区(HASH):使用哈希函数将数据分布到多个分区。
  • 键分区(KEY):类似于哈希分区,但使用 MySQL 的内部哈希算法。
  • 线性哈希分区(LINEAR HASH):一种特殊的哈希分区,适用于特定的负载和数据分布。
2.5.5 缓存结果

如果分页查询的结果不会频繁变化,可以考虑缓存查询结果。缓存可以显著减少数据库的负载,尤其是在高并发的场景下。

2.6 使用外部搜索引擎

对于特别复杂或数据量巨大的场景,可以考虑使用外部搜索引擎,如 Elasticsearch 或 Solr。这些工具专为处理大数据集和复杂查询而设计,通常比传统数据库更高效。

3. 实践中的注意事项

  • 合理选择分页大小: 分页大小直接影响查询性能和用户体验。较小的分页大小可以减少每次查询的负担,但会增加分页请求的次数。选择合适的分页大小需要权衡这两者的关系。

  • *监控和分析查询性能:*使用 MySQL 的性能监控工具(如 EXPLAIN 和慢查询日志)来分析查询的执行计划和性能瓶颈。

  • 考虑用户体验:在某些情况下,用户可能并不需要非常精确的分页数据。可以考虑使用“加载更多”按钮或无限滚动来替代传统分页。

4. 总结

本文,我们分析了 MySQL 的深度分页问题以及解决方案。对于 MySQL 中的深度分页,我们可以通过合理的优化策略来提高查询效率。具体选用什么方案,我们需要具体场景具体分析,但是核心还是在于理解数据库的工作原理,利用索引、优化查询策略、使用标记分页、分区表、缓存结果等些优化技术。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[LeetCode-Python版]21. 合并两个有序链表(迭代+递归两种解法)

题目 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 [1,2,4], l2 [1,3,4] 输出:[1,1,2,3,4,4] 示例 2: 输入:l1 [], l2 [] 输出&#x…

Git 安装教程

Git 是一个分布式版本控制系统,用于跟踪源代码的变化。它允许多个开发者协作开发同一个项目,能够有效管理项目的版本历史,便于协作与代码回溯。 Git官网 官网提供各种操作系统的安装程序。 step1.点击"Download for Windows"按钮&a…

Spring学习笔记-基础

前言:我是在哔哩哔哩上黑马程序员上找的课程。-----2024-12-16 官网Spring | Homehttps://spring.io/ Sping全家桶中重要三个: Spring Framework底层框架,在整个全家通中,所有的技术依赖它执行。 Spring Boot简化开发加速开发…

CNAS-AL06《实验室认可领域分类》修订,软件测试领域整体修订

为了不断适应行业发展的需要,进一步完善认可评审管理工作,进一步提高认可评审工作质量,CNAS认可委针对CNAS-AL06《实验室认可领域分类》进行了修订,并于近日正式发布。 原文件CNAS-AL06:20220101有25项一级代码,其中0…

单片机原理及应用笔记:单片机中断系统原理与项目实践

高金鹏:男,银川科技学院计算机与人工智能学院,2022级别计算机科学与技术本科生,单片机原理及应用课程第六组。 指导教师:王兴泽 电子邮件:高金鹏3535558665qq.com 个人CSDN:暴躁的海绵宝宝 暴躁的海绵宝…

【win10+RAGFlow+Ollama】搭建本地大模型助手(教程+源码)

一、RAGFlow简介 RAGFlow是一个基于对文档深入理解的开源RAG(Retrieval-augmented Generation,检索增强生成)引擎。 主要作用: 让用户创建自有知识库,根据设定的参数对知识库中的文件进行切块处理,用户向大…

在 Ubuntu 上部署 Terraform 管理平台:实现云基础设施的集中管理

简介 Terraform 是一款开源基础架构自动化工具,可让您通过命令行界面部署和管理数百台服务器。使用 Terraform,你可以通过在一个人类可读的文件中定义配置来构建、更改和管理你的基础架构。它支持许多云提供商,如 AWS、Azure、GCP 和阿里巴巴…

概率论得学习和整理25:EXCEL 关于直方图/ 频度图 /hist图的细节,2种做hist图的方法

目录 1 hist图的特点 2 hist的设置技巧:直接生成的hist图往往很奇怪不好用:因为横轴的分组不对 3 如何修改分组 4 设置开放边界,把长尾合并,得到hist图1 5 用原始表得到频数表 6 用上面的频数图做柱状图,再修改&…

RabbitMQ的核心组件有哪些?

大家好,我是锋哥。今天分享关于【RabbitMQ的核心组件有哪些?】面试题。希望对大家有帮助; RabbitMQ的核心组件有哪些? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 RabbitMQ是一个开源的消息代理(Messag…

桥接模式的理解和实践

桥接模式(Bridge Pattern),又称桥梁模式,是一种结构型设计模式。它的核心思想是将抽象部分与实现部分分离,使它们可以独立地进行变化,从而提高系统的灵活性和可扩展性。本文将详细介绍桥接模式的概念、原理…

【原创教程】西门子1500TCP_UDP通信说明大全(下篇)

2.3.3 TRCV故障说明 通讯无法正常连接时,ERROR引脚和STATUS引脚得状态有助于我们判断错误得原因,根据下表得提示,快速排除问题。 2.3.4 TRCV使用 点击TRCV指令得右上角蓝色图标,打开开始组态画面,按照控制要求填写 EN_R:用于激活接收的控制参数,及何时使用TRCV的接收功…

Grafana配置告警规则推送企微机器人服务器资源告警

前提 已经部署Grafana,并且dashboard接入数据 大屏编号地址:Node Exporter Full | Grafana Labs 创建企微机器人 备注:群里若有第三方外部人员不能创建 机器人创建完成,记录下来Webhook地址 Grafana配置告警消息模板 {{ define &…

RabbitMQ如何构建集群?

大家好,我是锋哥。今天分享关于【RabbitMQ如何构建集群?】面试题。希望对大家有帮助; RabbitMQ如何构建集群? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在RabbitMQ中,集群(Cluster&#x…

JDK以及JRE

目录 1.常用的快捷键操作2.重要的dos命令3.Jre(java Runtime environment)4.Jdk(java development kit)5.安装JDK6.JDK的目录7.Jdk的环境变量配置8.写第一个java程序8.1 安装UE软件8.2 写第一个HelloWorld 9.java运行机制 1.常用的…

Groovy 语法快速入门

文章目录 1. Groovy 的特点2. 基本语法2.1. 变量2.2. 字符串2.3. 条件语句 3. 集合操作3.1. 列表(List)3.2. 映射(Map) 4. 循环语句4.1. 普通循环4.2. 闭包遍历 5. 方法定义6. 闭包(Closure)6.1. 定义与调用…

MySQL 事务管理

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 MySQL 事务管理 收录于专栏[MySQL] 本专栏旨在分享学习MySQL的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 CURD 不加控制&#xff0…

【大模型微调学习5】-大模型微调技术LoRA

【大模型微调学习5】-大模型微调技术LoRA LoRa微调1.现有 PEFT 方法的局限与挑战2.LoRA: 小模型有大智慧 (2021)3.AdaLoRA: 自适应权重矩阵的高效微调 (2023)4.QLoRA: 高效微调量化大模型 (2023) LoRa微调 1.现有 PEFT 方法的局限与挑战 Adapter方法,通过增加模型深…

Windows server服务器之网络安全管理(防火墙入站规则创建)

任务14.1 Windows server 防火墙的管理 系统防火墙概述:无论哪一种操作系统都有自己的防火墙,无论是客户端OS还是服务器端的NOS都有防火墙。 winr-control----打开控制面板 上图是Windows客户端的防火墙,三个重点要关注的内容;网…

【Python】PyWebIO 初体验:用 Python 写网页

目录 前言1 使用方法1.1 安装 Pywebio1.2 输出内容1.3 输入内容 2 示例程序2.1 BMI 计算器2.2 Markdown 编辑器2.3 聊天室2.4 五子棋 前言 前两天正在逛 Github,偶然看到一个很有意思的项目:PyWebIo。 这是一个 Python 第三方库,可以只用 P…

四、CSS3

一、CSS3简介 1、CSS3概述 CSS3 是 CSS2 的升级版本,他在CSS2的基础上,新增了很多强大的新功能,从而解决一些实际面临的问题。 CSS在未来会按照模块化的方式去发展:https://www.w3.org/Style/CSS/current-work.html …