昨天的美团面试题:谈谈MySQL的limit用法逻辑分页和物理分页

Posted 程序员老鬼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了昨天的美团面试题:谈谈MySQL的limit用法逻辑分页和物理分页相关的知识,希望对你有一定的参考价值。

来源:blog.csdn.net/lvoelife/article/details/81943070

物理分页为什么用limit




同理,逻辑分页和物理分页是有区别的


昨天的美团面试题:谈谈MySQL的limit用法、逻辑分页和物理分页


为什么逻辑分页占用较大的内存空间,比如我有一张表,表的信息是:

  
    
    
  
-- ------------------------------ 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

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

昨天的美团面试题:谈谈MySQL的limit用法、逻辑分页和物理分页


limit的效率问题


  • 我有一个需求,就是从vote_record_memory表中查出3600000到3800000的数据,此时在id上加个索引,索引的类型是Normal,索引的方法是BTREE,分别用两种方法查询

-- 方法1SELECT * FROM vote_record_memory vrm LIMIT 3600000,20000 ;
-- 方法2SELECT * FROM vote_record_memory vrm WHERE vrm.id >= 3600000 LIMIT 20000

昨天的美团面试题:谈谈MySQL的limit用法、逻辑分页和物理分页

你会发现,方法2的执行效率远比方法1的执行效率高,几乎是方法1的九分之一的时间。

为什么方法1的效率低,而方法二的效率高呢?

  • 分析一

因为在方法1中,我们使用的单纯的limit。limit随着行偏移量的增大,当大到一定程度后,会出现效率下降。而方法2用上索引加where和limit,性能基本稳定,受偏移量和行数的影响不大。

  • 分析二

我们用explain来分析

昨天的美团面试题:谈谈MySQL的limit用法、逻辑分页和物理分页
昨天的美团面试题:谈谈MySQL的limit用法、逻辑分页和物理分页



昨天的美团面试题:谈谈MySQL的limit用法、逻辑分页和物理分页

我不用索引查询到的结果和返回的时间和方法1的时间差不多:
SELECT * FROM vote_record_memory vrm WHERE vrm.id >= 3600000 LIMIT

  
    
    
  
20000 受影响的行: 0 时间: 0.196s

昨天的美团面试题:谈谈MySQL的limit用法、逻辑分页和物理分页

这也就是我们为什么尽量使用索引的原因。mysql索引方法一般有BTREE索引和HASH索引,hash索引的效率比BTREE索引的效率高,但我们经常使用BTREE索引,而不是hash索引。因为最重要的一点就是:Hash索引仅仅能满足”=”,”IN”和”<=>”查询,不能使用范围查询。

昨天的美团面试题:谈谈MySQL的limit用法、逻辑分页和物理分页

如果是范围查询,我们为什么用BTREE索引的原因。BTREE索引就是二叉树索引,学过数据结构的应该都清楚,这里就不赘述了。

limit物理分页


我们都知道limit一般有两个参数,X和Y,X表示跳过X个数据,读取Y个数据,我们就此来查询数据

昨天的美团面试题:谈谈MySQL的limit用法、逻辑分页和物理分页
昨天的美团面试题:谈谈MySQL的limit用法、逻辑分页和物理分页

如果是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;

昨天的美团面试题:谈谈MySQL的limit用法、逻辑分页和物理分页

因而,如果是用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;}

欢迎加入程序员交流群


鬼哥我创了几个技术交流群,大家在群里面都是九分聊技术、一分聊风雪~


如果你没有加群,那就赶紧扫描下方二维码、添加我的微信,我拉大家进群,记得备注:城市 + 昵称 + 技术方向 哦!




往期推荐







耗时数月整理出来的技术资源免费分享给大家
扫描下方二维码,回复关键字【技术福利】获取!
喜欢的这里报道
↘↘

以上是关于昨天的美团面试题:谈谈MySQL的limit用法逻辑分页和物理分页的主要内容,如果未能解决你的问题,请参考以下文章

面试官:谈谈MySQL的limit用法逻辑分页和物理分页

219期面试官:谈谈MySQL的limit用法逻辑分页和物理分页

一个妹子的美团面试经历,已成功拿到Offer

来之不易的美团面试,结果居然挂了

美团的测试面试题,真的很难吗?

美团优选大数据开发岗面试真题-附答案详细解析