mysql的limit用法、逻辑分页和物理分页
物理分页为什么用limit
在讲解limit之间,我们先说说分页的事情。
分页有逻辑分页和物理分页,就像删除有逻辑删除和物理删除。逻辑删除就是改变数据库的状态,物理删除就是直接删除数据库的记录,而逻辑删除只是改变该数据库的状态。例如:
同理,逻辑分页和物理分页是有区别的
物理分页 | 逻辑分页 | Cool |
---|---|---|
物理分页依赖的是某一物理实体,这个物理实体就是数据库,比如MySQL数据库提供了limit关键字,程序员只需要编写带有limit关键字的SQL语句,数据库返回的就是分页结果。 | 逻辑分页依赖的是程序员编写的代码。数据库返回的不是分页结果,而是全部数据,然后再由程序员通过代码获取分页数据,常用的操作是一次性从数据库中查询出全部数据并存储到List集合中,因为List集合有序,再根据索引获取指定范围的数据。 | 概念 |
每次都要访问数据库,对数据库造成的负担大 | 只需要访问一次数据库 | 数据库负担 |
每次只读取一部分数据,占用的内存空间较小 | 一次性将数据读取到内存,占用较大的内存空间。如果使用java开发,Java本身引用的框架就占用了很多内存,这无疑加重了服务器的负担。 | 服务器负担 |
每次需要数据时都访问数据库,能够获取数据库的最新状态,实时性强 | 因为一次性读入到内存,数据发生了改变,数据库逇最新状态无法实时反映到操作中 | 实时性 |
数据库量大、更新频繁的场合 | 数据量较小、数据稳定的场合 | 服务器负担 |
为什么逻辑分页占用较大的内存空间,比如我有一张表,表的信息是: |
-- ----------------------------
-- Table structure for vote_record_memory
-- ----------------------------
DROP TABLE IF EXISTS `vote_record_memory`;
CREATE TABLE `vote_record_memory` (`id` int(11) NOT NULL AUTO_INCREMENT,`user_id` varchar(20) NOT NULL,`vote_id` int(11) NOT NULL,`group_id` int(11) NOT NULL,`create_time` datetime NOT NULL,PRIMARY KEY (`id`),KEY `index_id` (`user_id`) USING HASH
) ENGINE=MEMORY AUTO_INCREMENT=3000001 DEFAULT CHARSET=utf8;
向该表中插入300万条数据后,再转储到桌面,查看转储后的SQL文件的属性:
这是多么庞大的数据,占用的内存多么可怕,为什么我们再选用数据库。这也是我们使用云服务器时,设定mysql的存储空间的大小。
我们一般不推荐使用逻辑分页,而使用物理分页。在使用物理分页的时候,就要考虑到limit的用法。
解释limit
limit X,Y
,跳过前X条数据,读取Y条数据
- X表示第一个返回记录行的偏移量,Y表示返回记录行的最大数目
- 如果X为0的话,即 limit 0, Y,相当于limit Y、
通过业务分析limit
- 我有一张工资表,只显示最新的前两条记录,同时进行员工姓名和工资提成备注查询
SELECTcue.real_name empName,zs.push_money AS pushMoney,zs.push_money_note AS pushMoneyNote,zs.create_datetime AS createTime
FROMzq_salary zs //主表
LEFT JOIN core_user_ext cue ON cue.id = zs.user_id //从表 on之后是从表的条件
WHEREzs.is_deleted = 0
AND (cue.real_name LIKE '%李%'OR zs.push_money_note LIKE '%测%'
)
ORDER BYzs.create_datetime DESC
LIMIT 2;就相当于
ORDER BYzs.create_datetime DESC
LIMIT 0,2;
limit的效率问题
- 我有一个需求,就是从vote_record_memory表中查出3600000到3800000的数据,此时在id上加个索引,索引的类型是Normal,索引的方法是BTREE,分别用两种方法查询
-- 方法1
SELECT * FROM vote_record_memory vrm LIMIT 3600000,20000 ;-- 方法2
SELECT * FROM vote_record_memory vrm WHERE vrm.id >= 3600000 LIMIT 20000
你会发现,方法2的执行效率远比方法1的执行效率高,几乎是方法1的九分之一的时间。
为什么方法1的效率低,而方法二的效率高呢?
- 分析一
因为在方法1中,我们使用的单纯的limit。limit随着行偏移量的增大,当大到一定程度后,会出现效率下降。而方法2用上索引加where和limit,性能基本稳定,受偏移量和行数的影响不大。
- 分析二
我们用explain来分析:
可见,limit语句的执行效率未必很高,因为会进行全表扫描,这就是为什么方法1扫描的的行数是400万行的原因。方法2的扫描行数是47945行,这也是为什么方法2执行效率高的原因。我们尽量避免全表扫描查询,尤其是数据非常庞大,这张表仅有400万条数据,方法1和方法就有这么大差距,可想而知上千万条的数据呢。
能用索引的尽量使用索引,type至少达到range级别,这不是我说的,这是阿里巴巴开发手册的5.2.8中要求的
我不用索引查询到的结果和返回的时间和方法1的时间差不多:
SELECT * FROM vote_record_memory vrm WHERE vrm.id >= 3600000 LIMIT
20000 受影响的行: 0 时间: 0.196s
这也就是我们为什么尽量使用索引的原因。mysql索引方法一般有BTREE索引和HASH索引,hash索引的效率比BTREE索引的效率高,但我们经常使用BTREE索引,而不是hash索引。因为最重要的一点就是:Hash索引仅仅能满足"=",“IN"和”<=>"查询,不能使用范围查询。
如果是范围查询,我们为什么用BTREE索引的原因。BTREE索引就是二叉树索引,学过数据结构的应该都清楚,这里就不赘述了。
limit物理分页
我们都知道limit一般有两个参数,X和Y,X表示跳过X个数据,读取Y个数据,我们就此来查询数据
页数 | 每页显示的行数 | limit语句 | 计算方式 |
---|---|---|---|
第一页 | 20 | limit 0,20 | limit 0*20,20 |
第二页 | 20 | limit 20,20 | limit 1*20,20 |
第三页 | 20 | limit 40,20 | limit 2*20,20 |
第四页 | 20 | limit 60,20 | limit 3*20,20 |
如果是SQL语句来进行分页的话,我们可以看到的是: |
-- 首页
SELECT * from vote_record_memory LIMIT 0,20;-- 第二页
SELECT * from vote_record_memory LIMIT 20,20;-- 第三页
SELECT * from vote_record_memory LIMIT 40,20;-- 第四页
SELECT * from vote_record_memory LIMIT 60,20;-- n页
SELECT * from vote_record_memory LIMIT (n-1)*20,20;
因而,如果是用java的话,我们就可以写一个方法,有两个参数,一个是页数,一个每页显示的行数
/*** @description 简单的模拟分页雏形* @author zby* @param currentPage 当前页* @param lines 每页显示的多少条* @return 数据的集合*/public List<Object> listObjects(int currentPage, int lines) {String sql = "SELECT * from vote_record_memory LIMIT " + (currentPage - 1) * lines + "," + lines;return null;}
参考https://www.cnblogs.com/tonghun/p/7122801.html
mysql的limit用法、逻辑分页和物理分页相关推荐
- pdo mysql limit_PHP mysql中limit用法详解(代码示例)
在MySQL中,LIMIT子句与SELECT语句一起使用,以限制结果集中的行数.LIMIT子句接受一个或两个offset和count的参数.这两个参数的值都可以是零或正整数. offset:用于指定要 ...
- mysql的limit和or_面试官:谈谈MySQL的limit用法、逻辑分页和物理分页
来源:blog.csdn.net/lvoelife/article/details/81943070 物理分页为什么用limit 在讲解limit之间,我们先说说分页的事情. 分页有逻辑分页和物理分页 ...
- 面试官:谈谈MySQL的limit用法、逻辑分页和物理分页
来源:blog.csdn.net/lvoelife/article/details/81943070 物理分页为什么用limit 在讲解limit之间,我们先说说分页的事情. 分页有逻辑分页和物理分页 ...
- Mysql的limit用法
在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能. Sql代码 SELECT * FROM table LIMIT [ ...
- Mysql之limit用法总结
LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数.LIMIT 接受一个或两个数字参数,参数必须是一个整数常量.如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定 ...
- SQL(基于MySQL)——LIMIT用法
mysql支持limit select * from tablename limit n,m n:表示从第几行开始,mysql的行数是从0开始标注. m:表示要显示几行: 例如:select * fr ...
- mysql delete limit用法_mysql delete limit 使用方法详解
mysql delete limit优点: 用于DELETE的MySQL唯一的LIMIT row_count选项用于告知服务器在控制命令被返回到客户端前被删除的行的最大值.本选项用于确保一个DELET ...
- MYSQL中LIMIT用法_后台分页
LIMIT是MySQL内置函数,其作用是用于限制查询结果的条数. 1)其语法格式如下: LIMIT[位置偏移量,]行数 其中,中括号里面的参数是可选参数,位置偏移量是指MySQL查询分析器要从哪一行开 ...
- mysql delete limit用法_你习惯delete语句后带上limit吗
声明:本文基于MySQL讲解. 先不说习惯不习惯的,很多人也许会惊讶:还可以这样操作?其实,大家对这个操作比较陌生,也不奇怪.因为,学海无涯呀~ 语法 这个用法的详细语法是这样的:delete fro ...
最新文章
- 数据库设计Step by Step (10)——范式化
- 《Java从入门到放弃》框架入门篇:hibernate中的多表对应关系(二)
- curl header设置参数
- java socket wex5,在wex5中如何一行代码更新数据
- SAP程序下载模板显示异常问题解析
- 智能用电计量管理系统 远程预付费管理系统的设计与应用
- Win10系统蓝屏错误DPC怎么解决【系统天地】
- TwinCAT 3 马达程序
- 变色龙安装苹果系统的步骤(学习笔记)
- html+css实现百度首页(简单版)
- 链接形式的客服代码 QQ客服代码
- 歌词欣赏《一程山水一程歌》
- 江苏省赛 JSCPC2018 K. 2018
- 新华三联合英特尔共同增强服务器内存的可靠性
- DICOM医学影像文件解析
- 手写Vuex核心原理,再也不怕面试官问我Vuex原理
- Just A Triangle
- 春节菲律宾之行--MALAPASCUA Island
- raid卷的作用_Raid卷详解
- Navicat查看数据库密码