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中百万级数据的查询优化 万级别的数据真的算不上什么大数据,但是这个档的数据确实考核了普通的查询语句的性能,不同的书写方法有着千差万别的性能,都在这个级别中显现出来了,它不仅考 ...
随机推荐
- Shell 脚本编程学习
本文为博主原创,转载请注明出处: 目录: 1. shell 变量 2. 运算符 3. if 语句 4.for 循环 5.while 语句 6. case 语法 7.跳出循环:continue 与 br ...
- 码农的转型之路-IoTBrowser(物联网浏览器)雏形上线
消失了半个月闭门造轮子去了,最近干了几件大事: 1.工控盒子,win10系统长时间跑物联网服务测试.运行快2周了,稳定性效果还满意,除了windows自动更新重启了一次. 2 .接触了一些新概念MQT ...
- [js] - 导航展出动画
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- [转帖]【最佳实践】prometheus 监控 sql server (使用sql_exporter)
https://www.cnblogs.com/gered/p/13535212.html 目录 [0]核心参考 [简述] [1]安装配置 sql_exporter [1.1]下载解压 sql_exp ...
- [转帖]【JVM】线程安全与锁优化
线程安全 1.定义 当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果 2. ...
- Docker 运行 Redis Rabbitmq seata-server ftp 的简单办法
公司里面用到了很多组件, 发现安装二进制太麻烦了, 所以想用Docker 进行安装. 这里面简单给总结一下就不在折腾了.. 1. redis docker run -d -p 6379:6379 -- ...
- 一文搞懂Go GC演进史,讲的太细致了!
最近在和 Go就业训练营 的朋友讨论Go GC的问题,发现了刘丹冰老师总结的内容,写的太好了,和大家分享一下. 我们的讨论和思考也整理到这篇文章中了,希望对你有启发. 垃圾回收(Garbage Col ...
- elementui 的tabs组件出现蓝色边框问题
elementui 的tabs组件出现蓝色边框问题 /deep/ .el-tabs__item:focus.is-active.is-focus:not(:active) { -webkit-box- ...
- Fabric区块链浏览器(3)
本文是区块链浏览器系列的第五篇,项目完整代码在这里. 在上一篇文章中给浏览器增加了简单的用户认证,至此浏览器的基本功能就已经大致完成了. 在这片文章中,我将使用kratos对区块链浏览器器进行重构,使 ...
- 在mac中双击执行python
执行python脚本 mac有内置的python,但还是建议你自己安装一个python,如果没有卸载mac自带的python2.7,当你需要使用python3执行脚本时,python命令需要改为pyt ...