MySQL百万级数据大分页查询优化的实现
前言:在数据库开发过程中我们经常会使用分页,核心技术是使用用limit start, count分页语句进行数据的读取。
一、MySQL分页起点越大查询速度越慢
直接用limit start, count分页语句,表示从第start条记录开始选择count条记录 :
select * from test limit start, count ;
当起始页较小时,查询没有性能问题,我们分别看下从10, 1000, 10000, 100000开始分页的执行时间(每页取20条)。
select * from test limit 10, 20 ; //0.002秒 select * from test limit 1000, 20 ; //0.011秒 select * from test limit 10000, 20 ; //0.027秒 select * from test limit 100000, 20 ; //0.057秒
我们已经看出随着起始记录的增加,时间也随着增大, 这说明分页语句limit跟起始页码是有很大关系的,那么我们把起始记录改为100w看下:
select * from test limit 1000000, 20 ; //0.682秒
我们惊讶的发现MySQL在数据量大的情况下分页起点越大查询速度越慢,300万条起的查询速度已经需要1.368秒钟。这是为什么呢?
因为limit 3000000,20的语法实际上是MySQL扫描到前3000020条数据,之后丢弃前面的3000000行,这个步骤其实是浪费掉的。
select * from test limit 3000000, 20 ; //1.368秒
从中我们也能总结出两件事情:
(1) limit语句的查询时间与起始记录的位置成正比
(2) MySQL的limit语句是很方便,但是对记录很多的表并不适合直接使用。
二、 limit大分页问题的性能优化方法
(1)利用表的覆盖索引来加速分页查询
MySQL的查询完全命中索引的时候,称为覆盖索引,是非常快的。因为查询只需要在索引上进行查找之后可以直接返回,而不用再回表拿数据。
在我们的例子中,我们知道id字段是主键,自然就包含了默认的主键索引。现在让我们看看利用覆盖索引的查询效果如何。
select id from test limit 1000000, 20 ; //0.2秒
那么如果我们也要查询所有列,如何优化?
优化的关键是要做到让MySQL每次只扫描20条记录,我们可以使用limit n,这样性能就没有问题,因为MySQL只扫描n行。我们可以先通过子查询先获取起始记录的id,然后根据Id拿数据:
select * from test where id>=(select id from test limit 1000000,1) limit 20;
(2)延迟关联
和上述的子查询做法类似,我们可以使用JOIN,先在索引列上完成分页操作,然后再回表获取所需要的列。
select a.* from test a inner join (select id from test limit 1000000,20) b on a.id=b.id;
注意:如果不使用ORDER BY对主键或者索引字段进行排序,结果集返回不稳定(如某次返回1,2,3,另外的一次返回2,1,3)。
(3)用上次分页的最大id优化
优化思路是使用某种变量记录上一次数据的位置,下次分页时直接从这个变量的位置开始扫描,从而避免MySQL扫描大量的数据再抛弃的操作。
例如:先找到上次分页的最大ID,然后利用id上的索引来查询:
select * from test where id>1000000 limit 100 ;
说明:优化方法中所有的例子都是基于id为主键这个前提,不能使用索引字段,否则会出现返回数据记录数不对的情况。
MySQL百万级数据大分页查询优化的实现的更多相关文章
- MySQL 百万级数据量分页查询方法及其优化
方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N 适应场景: 适用于数据量较少的情况(元组百/千级) 原因/缺 ...
- PHP+MySQL百万级数据插入的优化
插入分析 MySQL中插入一个记录需要的时间由下列因素组成,其中的数字表示大约比例: 连接:(3) 发送查询给服务器:(2) 分析查询:(2) 插入记录:(1x记录大小) 插入索引:(1x索引) 关闭 ...
- Mysql百万级数据索引重新排序
参考https://blog.csdn.net/pengshuai007/article/details/86021689中思路解决自增id重排 方式一 alter table `table_name ...
- MySQL百万级数据分页查询及优化
方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N 适应场景: 适用于数据量较少的情况(元组百/千级) 原因/缺 ...
- mysql百万级数据分页查询缓慢优化-实战
作为后端攻城狮,在接到分页list需求的时候,内心是这样的 画面是这样的 代码大概是这样的 select count(id) from … 查出总数 select * from …. li ...
- Mysql百万级数据查询优化
1. 直接用limit start, count分页语句, 也是我程序中用的方法: select * from product limit start, count当起始页较小时,查询没有性能问题 ...
- Mongo查询百万级数据性能问题及JAVA优化问题
Mongo查询百万级数据 使用分页 skip和limit 效率会相当慢 那么怎么解决呢 上代码 全部查询数据也会特别慢 Criteria criteria = new Criteria(); ...
- Mysql百万数据量级数据快速导入Redis
前言 随着系统的运行,数据量变得越来越大,单纯的将数据存储在mysql中,已然不能满足查询要求了,此时我们引入Redis作为查询的缓存层,将业务中的热数据保存到Redis,扩展传统关系型数据库的服务能 ...
- mysql数据库千万级别数据的查询优化和分页测试
原文地址:原创 mysql数据库千万级别数据的查询优化和分页测试作者:于堡舰 本文为本人最近利用几个小时才分析总结出的原创文章,希望大家转载,但是要注明出处 http://blog.sina.com. ...
- Sql Server中百万级数据的查询优化
原文:Sql Server中百万级数据的查询优化 万级别的数据真的算不上什么大数据,但是这个档的数据确实考核了普通的查询语句的性能,不同的书写方法有着千差万别的性能,都在这个级别中显现出来了,它不仅考 ...
随机推荐
- Contest3376 - 2024寒假集训-排位赛竞赛(一)
A: 幂位和 高精度. 用高精度加法或乘法算出\(2^{1000}\),再将各位累加即为答案. #include <bits/stdc++.h> using namespace std; ...
- C#实现斐波拉切数列求和
C#实现斐波拉切数列求和 private void button1_Click(object sender, EventArgs e) { listBox1.Items.Clear();//清空Lis ...
- 11-verilog-有限状态机
有限状态机 写RTL的时候,实现一个功能的时候有很多种方法 将系统划分为多个状态,状态之间有状态的转移,第一步,第二步......形成有限状态机 流水线技术设计,从输入到输出有多个步骤,多个步骤可以并 ...
- APP Inventor的tcp连接扩展插件ClientSocketAl2Ext
参考原文:https://www.cnblogs.com/bemfa/p/13390251.html 下载地址:https://wwtl.lanzoum.com/ik0Ky1clu41a B站关联学习 ...
- IBM java的分析工具(ga和ha)学习和整理
IBM java的分析工具(ga和ha)学习和整理 背景 前几天学习了整理了 jca 工具 今天继续学习一下 ga工具 ga 工具主要是分析gclog相关. 可以很直观的进行gclog的分析和展示. ...
- [转帖]Linux中的lstopo命令(详细指南)
https://juejin.cn/post/7117544110856077343 目录: 简介 语法 命令 总结 参考文献 介绍 lstopo命令是用来显示系统的拓扑结构的.它提供了关于NUMA内 ...
- Nginx双层域名时 iframe嵌入/跳转页面的处理过程
Nginx双层域名时 iframe嵌入/跳转页面的处理过程 背景 两年前在上一家公司内遇到一个Nginx的问题 当时的场景是 双层nginx代理时(一层域名侧, 一层拆分微服务的网关层) 程序里面会打 ...
- ESXi上面虚拟机磁盘损坏修复案例
事故情况 最近同事反馈, 一个文件更新后出现了文件部分不可读的情况 具体现象为: 前端功能打开白屏 后端文件 前面93行不显示, notepad++打开都是 NULL 黑框. 然后重新覆盖文件, 有概 ...
- 一文搞懂Redis
作者: 京东物流 刘丽侠 姚再毅 康睿 刘斌 李振 一.Redis的特性 1.1 Redis为什么快? 基于内存操作,操作不需要跟磁盘交互,单次执行很快 命令执行是单线程,因为是基于内存操作,单次执行 ...
- Java单元测试浅析(JUnit+Mockito)
作者:京东物流 秦彪 1. 什么是单元测试 (1)单元测试环节: 测试过程按照阶段划分分为:单元测试.集成测试.系统测试.验收测试等.相关含义如下: 1) 单元测试: 针对计算机程序模块进 ...