Mysql分页查询性能分析
前言
【PS:原文手打,转载说明出处,博客园】
看过一堆的百度,最终还是自己做了一次实验,本文基于Mysql5.7.17版本,Mysql引擎为InnoDB,编码为utf8,排序规则为utf8_general_ci
网络搜索查询语句
Sql分页查询基于LIMIT,如下:
select * from SysTestUser order by Id LIMIT ;
select * from SysTestUser order by Id LIMIT ,;
网络上各说风云,有下面几种写法说速度快
1:如下子查询
select * from SysTestUser where Id in( select Id from (select Id from SysTestUser order by Id LIMIT ,) t );
2:如下图
select Id from SysTestUser order by Id LIMIT ,;
select * from SysTestUser where id in(,,,,,,,,,) order by Id ;
3:如下
select * from SysTestUser where id>=(select id from SysTestUser order by id limit ,) limit ;
实践出真知
我们新建一张表(PS:不要在意每个字段类型,这张表只是测试使用。)
-- ----------------------------
-- Table structure for SysTestUser
-- ----------------------------
DROP TABLE IF EXISTS `SysTestUser`;
CREATE TABLE `SysTestUser` (
`Id` int() NOT NULL AUTO_INCREMENT COMMENT 'Id',
`UserName` varchar() NOT NULL COMMENT '姓名',
`Sex` tinyint() NOT NULL COMMENT '性别',
`Height` decimal(,) NOT NULL COMMENT '身高',
`Age` smallint() NOT NULL COMMENT '年龄',
`Brithday` datetime NOT NULL COMMENT '生日',
`CreationTime` datetime NOT NULL COMMENT '创建时间',
`LastModificationTime` datetime NOT NULL COMMENT '修改时间',
`IsDeleted` bit() NOT NULL COMMENT '是否软删除',
PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8 COMMENT='测试用户表';
然后模拟了5038960条数据进库,分别进行查询,如下结果
无条件查询
select * from SysTestUser order by Id LIMIT ,;
80万=0.325
140万=0.579
500万=2.0 select * from SysTestUser where Id in( select Id from
(select Id from SysTestUser order by Id LIMIT ,) t );
80万=0.65
140万=1.179
500万=4.0 select Id from SysTestUser order by Id LIMIT ,;
select * from SysTestUser where id in(,,,,,,,,,) order by Id ;
80万=0.225
14万=0.39
500万=.368s select * from SysTestUser where id>=(select id from SysTestUser order by id limit ,) limit ;
80万=0.225
140万=0.397
500万=1.363
有条件查询(PS,字段没添加任何索引,由于批量新增,UserName=string+Id来着)
select * from SysTestUser where UserName like 'string%' and age= order by Id LIMIT ,;
80万=0.4
140万=0.71
500万=2.5 select * from SysTestUser where Id in( select Id from
(select Id from SysTestUser where UserName like 'string%' and age= order by Id LIMIT ,) t );
80万=0.33
140万=0.59
500万=2.06 select Id from SysTestUser where UserName like 'string%' and age= order by Id LIMIT ,;
select * from SysTestUser where id in(,,,,,,,,,) order by Id ;
80万=0.33
140万=0.59
500万=2.07 select * from SysTestUser where id>=(select id from SysTestUser where UserName like 'string%' and age= order by id limit ,) limit ;
80万=0.33
140万=0.59
500万=2.046
测试结论
百万级数据分页的情况下,以上方式都能够忍受,当数据量达到五百万的时候,需要的查询时间直接让人无法忍受了
处理方式
百万级以内的分页,无所谓写法,随便写没啥区别,百万级以上的,又需要查询分页查询的,可以使用以下方式。
select * from SysTestUser where ID> limit
select * from SysTestUser where ID> and UserName like 'string%' limit
至于ID哪里拿,怎么拿我给的建议是,第一页分页不管以何种方式写都很快,此时数据显示到前端,当点击下一页时,带上maxId or minID,这个看排序情况
这个时候的上面的ID是大于还是小于也看排序情况,我就不一一的写出来了。
结尾
大表分页是一件很头疼的事情,在实际业务场景能避免尽量避免,如果避免不了的情况下,尽量借助扩展表,缓存的形式来处理
例如:查询总条数,这个是避免不了的消耗的情况,完全可以写个计数器
在例如查询用户订单列表,完全可以使用Redis缓存用户订单信息等
不要用小刀来杀牛,杀不动
Mysql分页查询性能分析的更多相关文章
- MySQL分页查询性能优化
当需要从数据库查询的表有上万条记录的时候,一次性查询所有结果会变得很慢,特别是随着数据量的增加特别明显,这时需要使用分页查询.对于数据库分页查询,也有很多种方法和优化的点.下面简单说一下我知道的一些方 ...
- mysql、sql server、oracle数据库分页查询及分析(操作手册)
1.mysql分页查询 方式1: select * from table order by id limit m, n; 该语句的意思为,查询m+n条记录,去掉前m条,返回后n条记录.无疑该查询能够实 ...
- MySQL 慢查询日志分析及可视化结果
MySQL 慢查询日志分析及可视化结果 MySQL 慢查询日志分析 pt-query-digest分析慢查询日志 pt-query-digest --report slow.log 报告最近半个小时的 ...
- SQL查询性能分析之(not in)、(and not)、()、(!=)性能比较
SQL查询性能分析之(not in).(and not).().(!=)性能比较 SQL Server Bruce 3年前 (2013-01-08) 3284浏览 0评论 <:article c ...
- MySQL分页查询的性能优化
MySQL limit分页查询的性能优化 Mysql的分页查询十分简单,但是当数据量大的时候一般的分页就吃不消了. 传统分页查询:SELECT c1,c2,cn… FROM table LIMIT n ...
- MySQL分页查询大数据量优化方法
方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N适应场景: 适用于数据量较少的情况(元组百/千级)原因/缺点: ...
- mysql分页查询语法
一.limit语法 SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset LIMIT 子句可以被用于强制 SELECT 语句返回指 ...
- MySQL之查询性能优化(四)
优化特定类型的查询 COUNT()的作用 COUNT()是一个特殊函数,有两个非常不同的作用:它可以统计某个列值的数量,也可以统计行数.在统计列值时要求列值是非空的(不统计NULL). 如果在COUN ...
- 使用聚集索引和非聚集索引对MySQL分页查询的优化
内容摘录来源:MSSQL123 ,lujun9972.github.io/blog/2018/03/13/如何编写bash-completion-script/ 一.先公布下结论: 1.如果分页排序字 ...
随机推荐
- Java 8新特性探究(一) JEP126特性lambda表达式和默认方法
Lambda语法 函数式接口 函数式接口(functional interface 也叫功能性接口,其实是同一个东西).简单来说,函数式接口是只包含一个方法的接口.比如Java标准库中的java.la ...
- android官方技术文档翻译——Android Lint
本文译自androd官方技术文档<Android Lint>,原文地址:http://tools.android.com/tips/lint. 本文地址:http://blog.csdn. ...
- javascript语法之for-in语句
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 干掉头疼的finished with non-zero exit value 2
很多次会出现 finished with non-zero exit value 2 . Error:Execution failed for task ':app:dexDebug'. > ...
- 浅析GDAL库C#版本支持中文路径问题
GDAL库对于C#的支持问题还是蛮多的,对于中文路径的支持就是其中之一(另一个就是通过OGR库获取图形的坐标信息). 关于C#支持中文路径,看过我之前博客的应该都不陌生,如果使用的是我修改过的GDAL ...
- 使用Android Support Design 控件TabLayout 方便快捷实现选项卡功能
1.概述 TabLayout是在2015年的google大会上,google发布了新的Android Support Design库的新组件之一,以此来全面支持Material Design 设计风格 ...
- SQL-Teradata基础
1.创建一个和表 pnr_1 结构一样的表 Create table pnr_2 as pnr_1 with no data 不含数据 Create table pnr_2 as pnr_1 wit ...
- Android 之dragger使用
1.依赖的注入和配置独立于组件之外,注入的对象在一个独立.不耦合的地方初始化,这样在改变注入对象时,我们只需要修改对象的实现方法,而不用大改代码库. 2.依赖可以注入到一个组件中:我们可以注入这些依赖 ...
- Unity C# 自定义TCP传输协议以及封包拆包、解决粘包问题
本文只是初步实现了一个简单的TCP自定协议,更为复杂的协议可以根据这种方式去扩展. TCP协议,通俗一点的讲,它是一种基于socket传输的由发送方和接收方事先协商好的一种消息包组成结构,主要由消息头 ...
- 【LaTeX排版】LaTeX论文排版<二>
1.目录的生成 直接使用命令\tableofcontents即可.其默认格式如下: 我们会发现,这样的格式不一定是我们所期望的.比如说,我们也希望章标题与页码之间也有点连线,并且也希望将致谢. ...