mysql的limit用法、逻辑分页和物理分页

mysql的limit用法、逻辑分页和物理分页参考 https www cnblogs com tonghun p 7122801 html 物理分页为什么用 limit 在讲解 limit 之间 我们先说说分页的事情 分页有逻辑分页和物理分页 就像删除有逻辑删除和物理删除 逻辑删除就是改变数据库的状态 物理删除就是直接删除数据库的记录 而逻辑删除只是改变该数据库的状态 例如同理 逻辑分页和物理分页是有区别的

参考https://www.cnblogs.com/tonghun/p/7122801.html


物理分页为什么用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= DEFAULT CHARSET=utf8; 

解释limit

limit X,Y ,跳过前X条数据,读取Y条数据

  • X表示第一个返回记录行的偏移量,Y表示返回记录行的最大数目
  • 如果X为0的话,即 limit 0, Y,相当于limit Y、

通过业务分析limit

  • 我有一张工资表,只显示最新的前两条记录,同时进行员工姓名和工资提成备注查询
SELECT cue.real_name empName, zs.push_money AS pushMoney, zs.push_money_note AS pushMoneyNote, zs.create_datetime AS createTime FROM zq_salary zs //主表 LEFT JOIN core_user_ext cue ON cue.id = zs.user_id //从表 on之后是从表的条件 WHERE zs.is_deleted = 0 AND ( cue.real_name LIKE '%李%' OR zs.push_money_note LIKE '%测%' ) ORDER BY zs.create_datetime DESC LIMIT 2; 就相当于 ORDER BY zs.create_datetime DESC LIMIT 0,2; 

这里写图片描述

limit的效率问题

  • 我有一个需求,就是从vote_record_memory表中查出到的数据,此时在id上加个索引,索引的类型是Normal,索引的方法是BTREE,分别用两种方法查询
-- 方法1 SELECT * FROM vote_record_memory vrm LIMIT ,20000 ; -- 方法2 SELECT * FROM vote_record_memory vrm WHERE vrm.id >=  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的时间差不多:














limit物理分页

页数每页显示的行数limit语句计算方式
第一页20limit 0,20limit 0*20,20
第二页20limit 20,20limit 1*20,20
第三页20limit 40,20limit 2*20,20
第四页20limit 60,20limit 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://javaforall.net/218204.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 上午7:49
下一篇 2026年3月18日 上午7:49


相关推荐

  • 怎么创建自己的网站?创建自己网站的步骤「建议收藏」

    怎么创建自己的网站?创建自己网站的步骤「建议收藏」随着互联网的不断发现,越来越多的个人站长在互联网上获得不错的流量。也有很多的企业通过自己搭建网站创建属于自己的企业网站,也获得不错的效果。在互联网风口上,如果你还不做一个网站,那真的损失太大了。为了让广大互联网工作中获利今天牛商网就为大家解答怎么创建自己的网站?创建自己网站的步骤有哪些?1、自己建站第一步:购买域名和服务器。网站的域名和服务器是一个网站的基础配件,域名就相当于你网站的地址,当别人输入你的域名的时候就可以访问你的网站。而服务器就相当于一个房子,用来存放你网站的文件和内容的。同时域名和

    2022年6月18日
    30
  • 哈希冲突原因「建议收藏」

    哈希冲突原因「建议收藏」哈希计算就是努力的把比较大的数据存放到相对较小的空间中。最常见的哈希算法是取模法。下面简单讲讲取模法的计算过程。比如:数组的长度是5。这时有一个数据是6。那么如何把这个6存放到长度只有5的数组中呢。按照取模法,计算6%5,结果是1,那么就把6放到数组下标是1的位置。那么,7就应该放到2这个位置。到此位置,哈斯冲突还没有出现。这时,有个数据是11,按照取模法,11%5=1,也等于1。那

    2022年6月18日
    38
  • Python读取h5文件_html python

    Python读取h5文件_html python原文链接:https://blog.csdn.net/leibaojiangjun1/article/details/53635353 h5接受的数据是矩阵跟mat方法一致,但是具有更强的压缩性能使用hdf5依赖于python的工具包:h5pyimporth5py #导入工具包importnumpyasnp#HDF5的写入:imgData=np.zeros((30,3…

    2025年10月11日
    5
  • HashMap扩容机制解读[通俗易懂]

    HashMap扩容机制解读[通俗易懂]扩容机制什么时候需要扩容:当hashmap中的元素个数超过数组大小*loadFactor(负载因子)时,就会进行数组扩容,loadFactor的默认值(DEFAULT_LOAD_FACTOR)是0.75这是一个折中的取值,也就是说,默认情况下数组大小为16,那么当hashmap中的元素个数超过16*0.75=12(阈值或者边界值的时候)就把数组的大小扩展Wie2*16=32,然后重新计算出每个元素在数组中的位置,而这是一个非常耗性能的操作,所以我们最好能够提前预知并设置元素的个数。注

    2022年6月17日
    31
  • Android中px和dip的区别

    Android中px和dip的区别

    2021年8月25日
    63
  • redis实现分布式锁的原理_Redis作为分布式锁原理

    redis实现分布式锁的原理_Redis作为分布式锁原理一、写在前面现在面试,一般都会聊聊分布式系统这块的东西。通常面试官都会从服务框架(SpringCloud、Dubbo)聊起,一路聊到分布式事务、分布式锁、ZooKeeper等知识。所以咱们这篇文章就来聊聊分布式锁这块知识,具体的来看看Redis分布式锁的实现原理。说实话,如果在公司里落地生产环境用分布式锁的时候,一定是会用开源类库的,比如Redis分布式锁,一般就是…

    2025年7月25日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号