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

从63 秒到 0.482 秒:深入剖析 MySQL 分页查询优化

在日常开发中,数据库查询性能问题就像潜伏的“地雷”,总在高并发或数据量庞大的场景下引爆。尤其是当你运行一条简单的分页查询时,结果却让用户苦苦等待,甚至拖垮了系统。这种情况你是否遇到过?

你可能会想:“我的表已经建立了索引,为什么还是这么慢?” 或者:“难道数据库引擎就没办法高效处理大数据分页吗?”

这篇博客将从 MySQL 索引机制入手,深入剖析其底层原理(B+树),结合实际场景讲解分页查询优化的技巧,并通过实验数据展示优化效果。只需稍加调整,就能让查询从 几十秒 缩短到 几百毫秒

1. MySQL 索引机制

1.1 索引是什么?

索引是一种提高查询速度的数据结构。它的作用类似于书的目录,可以帮助 MySQL 快速找到目标数据,而不是逐页翻找。

1.2 MySQL 的索引类型
  1. 聚簇索引(Clustered Index)

    • InnoDB 存储引擎默认的主键索引。
    • 特点:数据和索引存储在一起,叶子节点存储的是完整行的数据。
    • 每个表只能有一个聚簇索引。
    • 示例:假设一张用户表以 id 为主键,索引结构如下:
      根节点 → 中间节点 → 叶子节点(存储完整行数据)
      
  2. 辅助索引(Secondary Index)

    • 除主键外的其他索引,例如普通索引和唯一索引。
    • 特点:叶子节点存储的是主键值,通过主键值回表查询完整数据。
    • 适用场景:用于加速非主键列的查询。
1.3 MySQL 缓存机制的变化
  • MySQL 8.0 删除了查询缓存(Query Cache)

    • 原因:查询缓存频繁失效,影响性能,在高并发写场景下尤为明显。
    • 查询缓存的替代:更高效的优化器和 InnoDB 缓存机制。
  • MySQL 的 Buffer Pool

    • 依旧是核心性能优化手段。
    • 功能:将数据页、索引页缓存到内存中,减少磁盘 I/O。
    • 特点:即使查询缓存被删除,Buffer Pool 仍然支持高效的索引查询和数据读取。

2. 索引的底层原理

2.1 什么是 B+树?

B+树是一种平衡多路搜索树,广泛应用于数据库和文件系统中,用于存储索引。

2.2 B+树的结构
  1. 非叶子节点
    • 只存储索引键,起到导航作用。
    • 减少了节点大小,提高了节点的分支因子。
  2. 叶子节点
    • 存储所有实际数据(聚簇索引)或主键值(辅助索引)。
    • 通过链表指针串联,便于范围查询。
2.3 B+树的特点
  1. 平衡性:所有叶子节点都在同一层,查询效率稳定。
  2. 磁盘友好:每个节点存储多个索引键,减少了磁盘 I/O 次数。
  3. 范围查询高效:叶子节点的链表结构支持顺序遍历。
    在这里插入图片描述
2.4 为什么 MySQL 使用 B+树?
  • 相比 B 树:B+树的非叶子节点存储更多的索引键,更适合大规模数据存储。
  • 相比哈希索引:B+树支持范围查询和排序,而哈希索引只支持等值查询。

3. 优化 SQL 排序分页查询的场景

3.1 问题描述

假设我们需要从 content 表中查询最近的第 2000000 条到第 2000010 条数据:

SELECT * FROM content ORDER BY create_time DESC LIMIT 2000000, 10;
3.2 存在的问题
  1. 大偏移量(OFFSET)

    • 数据库需要扫描并丢弃前 2000000 条记录,浪费资源。
    • 即使有索引,MySQL 仍需逐一读取和排序这些记录。
  2. 全表扫描的风险

    • 如果 create_time 没有索引,查询会触发全表扫描。
3.3 优化思路
  • 利用子查询限定范围
    • 子查询通过索引直接定位目标主键范围。
    • 主表查询通过主键精确匹配记录,减少无效扫描。
3.4 优化前后对比

优化前 SQL

SELECT * FROM content ORDER BY create_time DESC LIMIT 2000000, 10;

优化后 SQL

SELECT * 
FROM content 
INNER JOIN (SELECT id FROM content ORDER BY create_time DESC LIMIT 2000000, 10
) temp_content 
ON content.id = temp_content.id;
3.5 优化前后性能数据
  • 优化前
    • 查询耗时:63s
    • 原因:扫描大量数据并丢弃前 2000000 条记录,逻辑开销大。
  • 优化后
    • 查询耗时:0.482s
    • 原因:子查询通过索引快速定位目标记录范围,主表只查询需要的数据。

4. 为什么优化后性能提升显著?

4.1 子查询利用索引
  • 子查询 SELECT id FROM content ORDER BY create_time DESC LIMIT 2000000, 10 利用了 create_time 索引。
  • 索引通过 B+树快速定位到目标范围,减少了全表扫描。
4.2 减少了无效的数据处理
  • 优化前:扫描并丢弃了 2000000 条数据。
  • 优化后:只查询需要的数据。
4.3 高效利用缓存
  • 优化后的查询范围更小,Buffer Pool 的命中率更高。
  • 避免了大范围扫描导致的缓存失效问题。
4.4 排序开销显著降低
  • 子查询已经完成排序,主查询不需要重复排序,节省了计算资源。

相关文章:

从63 秒到 0.482 秒:深入剖析 MySQL 分页查询优化

在日常开发中,数据库查询性能问题就像潜伏的“地雷”,总在高并发或数据量庞大的场景下引爆。尤其是当你运行一条简单的分页查询时,结果却让用户苦苦等待,甚至拖垮了系统。这种情况你是否遇到过? 你可能会想&#xff1…...

细说机器学习算法之过拟合与欠拟合

系列文章目录 第一章:Pyhton机器学习算法之KNN 第二章:Pyhton机器学习算法之K—Means 第三章:Pyhton机器学习算法之随机森林 第四章:Pyhton机器学习算法之线性回归 第五章:Pyhton机器学习算法之有监督学习与无监督…...

C/C++ 虚函数

虚函数的定义 虚函数是指在基类内部声明的成员函数前面添加关键字 virtual 指明的函数虚函数存在的意义是为了实现多态,让派生类能够重写(override)其基类的成员函数派生类重写基类的虚函数时,可以添加 virtual 关键字,但不是必须这么做虚函…...

【3GPP】【5G】注销流程(Deregistration procedures)

1. 欢迎大家订阅和关注,精讲3GPP通信协议(2G/3G/4G/5G/IMS)知识点,专栏会持续更新中.....敬请期待! 目录 3.1.2 Deregistration procedures 3.1.2.1 UE-initiated Deregistration 3.1.2.2 Network-initiated Deregistration 3.1.2 Deregistration procedures 注销流程…...

【小游戏篇】三子棋游戏

硬控我一上午&#xff0c;小编还是太菜了&#xff0c;大家可以自行升级电脑难度&#xff0c;也可以升级游戏到五子棋 1.game.h #pragma once #include<stdio.h> #include<stdlib.h> #include<time.h> #define ROW 3 #define COL 3//初始化棋盘 void InitBoa…...

7-Zip Mark-of-the-Web绕过漏洞复现(CVE-2025-0411)

免责申明: 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 0x0…...

2025年国产化推进.NET跨平台应用框架推荐

2025年国产化推进.NET跨平台应用框架推荐 1. .NET MAUI NET MAUI是一个开源、免费&#xff08;MIT License&#xff09;的跨平台框架&#xff08;支持Android、iOS、macOS 和 Windows多平台运行&#xff09;&#xff0c;是 Xamarin.Forms 的进化版&#xff0c;从移动场景扩展到…...

关于ARM和汇编语言

一图流 ARM 计算机组成 输入设备 输出设备 存储设备 运算器 控制器 处理器读取内存程序执行的过程 取指阶段&#xff1a;控制器器通过地址总线向存储器发送想要获取的指令的地址编号&#xff0c;存储器将指定的指令发送给处理器 译码阶段&#xff1a;控制器对指令进行分…...

2024人工智能AI+制造业应用落地研究报告汇总PDF洞察(附原数据表)

原文链接&#xff1a; https://tecdat.cn/?p39068 本报告合集洞察深入剖析当前技术应用的现状&#xff0c;关键技术 创新方向&#xff0c;以及行业应用的具体情况&#xff0c;通过制造业具体场景的典型 案例揭示人工智能如何助力制造业研发设计、生产制造、运营管理 和产品服…...

QTableView和QTableWidget的关系与区别

QTableView 和 QTableWidget 都是 Qt 框架中用于显示表格数据的控件&#xff0c;但它们在设计和使用上有一些重要的区别。 QTableView 模型-视图架构&#xff1a;QTableView 是 Qt 模型-视图架构的一部分&#xff0c;它与模型&#xff08;如 QStandardItemModel 或自定义的 QA…...

Java导出通过Word模板导出docx文件并通过QQ邮箱发送

一、创建Word模板 {{company}}{{Date}}服务器运行情况报告一、服务器&#xff1a;总告警次数&#xff1a;{{ServerTotal}} 服务器IP:{{IPA}}&#xff0c;总共告警次数:{{ServerATotal}} 服务器IP:{{IPB}}&#xff0c;总共告警次数:{{ServerBTotal}} 服务器IP:{{IPC}}&#x…...

ESP8266 MQTT服务器+阿里云

MQTT私有平台搭建&#xff08;EMQX 阿里云&#xff09; 阿里云服务器 EMQX 搭建私有MQTT平台 1、搜索EMQX开源版本 2、查看各版本EMQX支持的UBUNTU版本 3、查看服务器Ubuntu版本 4、使用APT安装模式 5、按照官网指示安装并启动 6、下载安装MQTTX测试工具 7、设置云服务…...

css动画水球图

由于echarts水球图动画会导致ios卡顿&#xff0c;所以纯css模拟 展示效果 组件 <template><div class"water-box"><div class"water"><div class"progress" :style"{ --newProgress: newProgress % }"><…...

【设计模式-行为型】状态模式

一、什么是状态模式 什么是状态模式呢&#xff0c;这里我举一个例子来说明&#xff0c;在自动挡汽车中&#xff0c;挡位的切换是根据驾驶条件&#xff08;如车速、油门踏板位置、刹车状态等&#xff09;自动完成的。这种自动切换挡位的过程可以很好地用状态模式来描述。状态模式…...

2024.1.22 安全周报

政策/标准/指南最新动态 01 工信部印发《关于加强互联网数据中心客户数据安全保护的通知》 原文: https://www.secrss.com/articles/74673 互联网数据中心作为新一代信息基础设施&#xff0c;承载着千行百业的海量客户数据&#xff0c;是关系国民经济命脉的重要战略资源。…...

idea修改模块名导致程序编译出错

本文简单描述分别用Idea菜单、pom.xml文件管理项目模块module 踩过的坑&#xff1a; 通过idea菜单创建模块&#xff0c;并用idea菜单修改模块名&#xff0c;结构程序编译报错&#xff0c;出错的代码莫名奇妙。双击maven弹窗clean时&#xff0c;还是报错。因为模块是新建的&am…...

root用户Linux银河麒麟服务器安装vnc服务

安装必要桌面环境组件 yum install mate-session-manager -y mate-session #确定是否安装成功安装vnc服务器 yum install tigervnc-server -y切换到root为root得vnc设置密码 su root vncpasswd给root用户设置vnc服务器文件 vi /etc/systemd/system/vncserver:1.service [Un…...

CentOS 7使用RPM安装MySQL

MySQL是一个开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;允许用户高效地存储、管理和检索数据。它被广泛用于各种应用&#xff0c;从小型的web应用到大型企业解决方案。 MySQL提供了丰富的功能&#xff0c;包括支持多个存储引擎、事务能力、数据完整…...

OpenCV imread函数读取图像__实例详解

OpenCV imread函数读取图像__实例详解 本文目录&#xff1a; 零、时光宝盒 一、imread函数定义 二、imread函数支持的文件格式 三、imread函数flags参数详解 &#xff08;3.1&#xff09;、Flags-1时&#xff0c;样返回加载的图像&#xff08;使用alpha通道&#xff0c;否…...

激光线扫相机无2D图像的标定方案

方案一&#xff1a;基于运动控制平台的标定 适用场景&#xff1a;若激光线扫相机安装在可控运动平台&#xff08;如机械臂、平移台、旋转台&#xff09;上&#xff0c;且平台的运动精度已知&#xff08;例如通过编码器或高精度步进电机控制&#xff09;。 步骤&#xff1a; 标…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...

【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权

摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题&#xff1a;安全。文章将详细阐述认证&#xff08;Authentication) 与授权&#xff08;Authorization的核心概念&#xff0c;对比传统 Session-Cookie 与现代 JWT&#xff08;JS…...

JDK 17 序列化是怎么回事

如何序列化&#xff1f;其实很简单&#xff0c;就是根据每个类型&#xff0c;用工厂类调用。逐个完成。 没什么漂亮的代码&#xff0c;只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

密码学基础——SM4算法

博客主页&#xff1a;christine-rr-CSDN博客 ​​​​专栏主页&#xff1a;密码学 &#x1f4cc; 【今日更新】&#x1f4cc; 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 ​编辑…...

【前端实战】如何让用户回到上次阅读的位置?

目录 【前端实战】如何让用户回到上次阅读的位置&#xff1f; 一、总体思路 1、核心目标 2、涉及到的技术 二、实现方案详解 1、基础方法&#xff1a;监听滚动&#xff0c;记录 scrollTop&#xff08;不推荐&#xff09; 2、Intersection Observer 插入探针元素 3、基…...