MySQL(143)如何优化分页查询?(mysql高效分页查询)
itomcoil 2025-07-27 21:14 2 浏览
优化分页查询是提升数据库性能和用户体验的重要手段。特别是在处理大数据集时,分页查询的效率对系统性能有显著影响。以下是优化分页查询的详细步骤和代码示例。
一、传统分页查询
传统的分页查询使用 OFFSET 和 LIMIT 关键字,但是当 OFFSET 值很大时,性能会急剧下降,因为数据库需要扫描大量的行。
示例:
SELECT *
ORDER BY id OFFSET 10000 ROWS FETCH NEXT 10 ROWS ONLY;
这个查询在大数据集上会导致性能问题,因为数据 #技术分享 #掘金库在 OFFSET 部分扫描了大量的行。
二、优化分页查询
为了优化分页查询,可以使用多种技术:
- 基于索引的分页 :利用索引来快速定位分页起点。
- 延迟关联(Deferred Join) :先获取分页所需的主键,然后再进行关联查询。
- 预计算和缓存 :将分页结果预先计算并缓存。
1. 基于索引的分页
基于索引的分页通过使用自增主键或唯一索引,可以显著提高分页查询的性能。
示例:
假设我们有一个名为 employees 的表,其中包含以下字段:id 、name 和 email 。
SELECT *
WHERE id > ? ORDER BY id LIMIT 10;
在这种方式中,通过传递上一页最后一条记录的 id 作为参数,可以快速定位到下一页的数据。
Java代码示例:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class PaginationExample {
private static final String DB_URL = "jdbc:mysql://your_host/your_database"; private static final String DB_USER = "your_user"; private static final String DB_PASSWORD = "your_password";
public static void main(String[] args) { int lastId = 0;
try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) { String paginationQuery = "SELECT * FROM employees WHERE id > ? ORDER BY id LIMIT 10";
try (PreparedStatement stmt = conn.prepareStatement(paginationQuery)) { stmt.setInt(1, lastId); try (ResultSet rs = stmt.executeQuery()) { while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); String email = rs.getString("email"); System.out.printf("ID: %d, Name: %s, Email: %s%n", id, name, email);
lastId = id; } } } } catch (SQLException e) { e.printStackTrace(); } } }
2. 延迟关联(Deferred Join)
延迟关联技术通过先获取主键,然后再进行关联查询,减少了大表扫描的开销。
示例:
SELECT id
FROM employees
ORDER BY id
LIMIT 10 OFFSET 10000;
SELECT e.*
JOIN ( SELECT id FROM employees ORDER BY id LIMIT 10 OFFSET 10000 ) AS sub ON e.id = sub.id;
Java代码示例:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class DeferredJoinPaginationExample {
private static final String DB_URL = "jdbc:mysql://your_host/your_database"; private static final String DB_USER = "your_user"; private static final String DB_PASSWORD = "your_password";
public static void main(String[] args) { int offset = 10000; int limit = 10;
try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) { String getIdsQuery = "SELECT id FROM employees ORDER BY id LIMIT ? OFFSET ?"; List<Integer> ids = new ArrayList<>();
try (PreparedStatement getIdsStmt = conn.prepareStatement(getIdsQuery)) { getIdsStmt.setInt(1, limit); getIdsStmt.setInt(2, offset); try (ResultSet rs = getIdsStmt.executeQuery()) { while (rs.next()) { ids.add(rs.getInt("id")); } } }
if (!ids.isEmpty()) { String getEmployeesQuery = "SELECT * FROM employees WHERE id IN (" + String.join(",", ids.stream().map(String::valueOf).toArray(String[]::new)) + ") ORDER BY id";
try (PreparedStatement getEmployeesStmt = conn.prepareStatement(getEmployeesQuery); ResultSet rs = getEmployeesStmt.executeQuery()) { while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); String email = rs.getString("email"); System.out.printf("ID: %d, Name: %s, Email: %s%n", id, name, email); } } } } catch (SQLException e) { e.printStackTrace(); } } }
三、预计算和缓存
对于一些常用的分页查询,可以预先计算并缓存结果,以减少实时计算的开销。
示例:
可以使用 Redis 或其他缓存技术来缓存分页结果。
cache.set("employees_page_1", resultSet);
ResultSet cachedResultSet = cache.get("employees_page_1");
总结
优化分页查询的方法包括:
- 基于索引的分页 :通过使用索引字段来快速定位分页数据。
- 延迟关联 :先获取需要的主键,然后进行关联查询。
- 预计算和缓存 :将常用的分页结果预先计算并缓存。
通过这些方法,可以显著提高分页查询的性能,减少大数据集上的查询延迟。
相关推荐
- 字符串可以这样加索引,你知吗?(字符串怎么加)
-
相信大多数小伙伴跟咔咔一样,给字符串添加索引从未设置过长度,今天就来聊聊如何正确的给字符串加索引。一、如何建立索引大多数系统都会存在用户表,并且系统初始设计使用了手机号码登录的。这是产品提出了一个需求...
- MySQL高频函数Top10!数据分析效率翻倍,拒绝无效加班!
-
引言:为什么你的SQL代码又臭又长?“同事3行代码搞定的事,你写了30行?”“每次处理日期、字符串都抓狂,疯狂百度?”——不是你不努力,而是没掌握这些高频函数!本文精炼8年数据库开发经验,总结出10个...
- 上亿数据怎么玩深度分页?兼容MySQL + ES + MongoDB
-
推荐学习阿里P8MySQL,基础/索引/锁/日志/调优都不误,一锅深扒端给你“吃”完这本Java性能调优实战,MySQL+JVM+Tomcat等问题一键全消面试题&真实经历面试题:在数据量很大的情...
- Hive如何比较两张表所有字段的一致性
-
前言随着MySQL技术发展,通过垂直或水平拆分能够支持相当大的数据量,目前很多公司把SQLServer、Oracledb或其他数据库迁移到MySQL上,迁移数据量很大(数据库已经水平拆分成很多Sha...
- MySql:函数盘点(mysql函数用法)
-
一、MySQL函数1、数学函数常用的有:(1)ABS()绝对值(2)CEILING()大于等于我的最小整数(天花板)(3)FLOOR()小于等于我的最大整数(地板)(4)RAND()返回0~1...
- mysql的截取函数用法详解(mysql截取字符串函数的sql语句)
-
substring()函数测试数据准备:用法:以下语法是mysql自动提示的1:substirng(str,pos):从指定位置开始截取一直到数据完成str:需要截取的字段的pos:开始截取的位置。从...
- mysql拼接函数讲解及配合截取函数使用
-
在上一篇我们讲解了mysql的截取函数用法。本篇我们将讲解mysql的拼接函数以及配合截取函数实现当留言数字过多省略显示的场景。concat函数:把参数连成一个长字符串并返回(任何参数是NULL时返回...
- MySQL实现字段分割(一行转多行)(mysql 分割)
-
先看一下数据结构,我这里字段比较少,只弄了最重要的部分根据我们上次学到的LEFT()函数进行分组SELECTLEFT(provinces,6),COUNT(1)FROM`region_map_c...
- MySQL(143)如何优化分页查询?(mysql高效分页查询)
-
优化分页查询是提升数据库性能和用户体验的重要手段。特别是在处理大数据集时,分页查询的效率对系统性能有显著影响。以下是优化分页查询的详细步骤和代码示例。一、传统分页查询传统的分页查询使用OFFSET...
- Go语言实现连接MySql基础操作(golang mysql orm)
-
在Go中,可以使用database/sql包来连接和操作MySQL数据库。以下是一个简单的示例程序,它演示了如何连接MySQL数据库并执行查询操作:packagemainimpo...
- MySQL 如何巧妙解决 Too many connections 报错?
-
1.背景在日常的MySQL运维中,难免会出现参数设置不合理,导致MySQL在使用过程中出现各种各样的问题。今天,我们就来讲解一下MySQL运维中一种常见的问题:最大连接数设置不合理,一旦...
- MYSQL数据同步(mysql数据同步机制)
-
java开发工程师在实际的开发经常会需要实现两台不同机器上的MySQL数据库的数据同步,要解决这个问题不难,无非就是mysql数据库的数据同步问题。但要看你是一次性的数据同步需求,还是定时数据同步,亦...
- Go语言MySQL的简单应用(go mysql prepare)
-
要在Go中处理MySQL数据库,可以使用第三方包,例如go-sql-driver/mysql。以下是一个简单的示例代码:packagemainimport("dat...
- 最简洁详细的SSM框架整合(ssm框架完整的功能流程)
-
创建项目和SSM框架整合思路一、创建项目因为后面会配置springMVC,所以用IDEA的web骨架创建一个maven项目。创建项目目录如下,同时,项目需要的包和文件已手动创建好了:项目目录上图中,a...
- 部署canal server 1.1.5,消费mysql信息,订阅测试
-
一、CanalServer的核心架构CanalServer是阿里巴巴开源的MySQLbinlog增量订阅与消费组件,其架构设计围绕高可用、高性能、低延迟三大目标构建,主要包含以下核心...
- 一周热门
- 最近发表
- 标签列表
-
- ps图案在哪里 (33)
- super().__init__ (33)
- python 获取日期 (34)
- 0xa (36)
- super().__init__()详解 (33)
- python安装包在哪里找 (33)
- linux查看python版本信息 (35)
- python怎么改成中文 (35)
- php文件怎么在浏览器运行 (33)
- eval在python中的意思 (33)
- python安装opencv库 (35)
- python div (34)
- sticky css (33)
- python中random.randint()函数 (34)
- python去掉字符串中的指定字符 (33)
- python入门经典100题 (34)
- anaconda安装路径 (34)
- yield和return的区别 (33)
- 1到10的阶乘之和是多少 (35)
- python安装sklearn库 (33)
- dom和bom区别 (33)
- js 替换指定位置的字符 (33)
- python判断元素是否存在 (33)
- sorted key (33)
- shutil.copy() (33)