百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

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

ztj100 2024-12-18 18:21 21 浏览 0 评论

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

物理分页为什么用limit

在讲解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的用法。

往期:一年内容,200期Java面试题阶段汇总


解释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表中查出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和方法就有这么大差距,可想而知上千万条的数据呢。

往期:一年内容,200期Java面试题阶段汇总

能用索引的尽量使用索引,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个数据,我们就此来查询数据

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

相关推荐

SpringBoot整合SpringSecurity+JWT

作者|Sans_https://juejin.im/post/5da82f066fb9a04e2a73daec一.说明SpringSecurity是一个用于Java企业级应用程序的安全框架,主要包含...

「计算机毕设」一个精美的JAVA博客系统源码分享

前言大家好,我是程序员it分享师,今天给大家带来一个精美的博客系统源码!可以自己买一个便宜的云服务器,当自己的博客网站,记录一下自己学习的心得。开发技术博客系统源码基于SpringBoot,shiro...

springboot教务管理系统+微信小程序云开发附带源码

今天给大家分享的程序是基于springboot的管理,前端是小程序,系统非常的nice,不管是学习还是毕设都非常的靠谱。本系统主要分为pc端后台管理和微信小程序端,pc端有三个角色:管理员、学生、教师...

SpringBoot+LayUI后台管理系统开发脚手架

源码获取方式:关注,转发之后私信回复【源码】即可免费获取到!项目简介本项目本着避免重复造轮子的原则,建立一套快速开发JavaWEB项目(springboot-mini),能满足大部分后台管理系统基础开...

Spring Boot的Security安全控制——认识SpringSecurity!

SpringBoot的Security安全控制在Web项目开发中,安全控制是非常重要的,不同的人配置不同的权限,这样的系统才安全。最常见的权限框架有Shiro和SpringSecurity。Shi...

前同事2024年接私活已入百万,都是用这几个开源的SpringBoot项目

前言不得不佩服SpringBoot的生态如此强大,今天给大家推荐几款优秀的后台管理系统,小伙伴们再也不用从头到尾撸一个项目了。SmartAdmin...

值得学习的15 个优秀开源的 Spring Boot 学习项目

SpringBoot算是目前Java领域最火的技术栈了,除了书呢?当然就是开源项目了,今天整理15个开源领域非常不错的SpringBoot项目供大家学习,参考。高富帅的路上只能帮你到这里了,...

开发企业官网就用这个基于SpringBoot的CMS系统,真香

前言推荐这个项目是因为使用手册部署手册非常...

2021年超详细的java学习路线总结—纯干货分享

本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础...

jeecg-boot学习总结及使用心得(jeecgboot简单吗)

jeecg-boot学习总结及使用心得1.jeecg-boot是一个真正前后端分离的模版项目,便于二次开发,使用的都是较流行的新技术,后端技术主要有spring-boot2.x、shiro、Myb...

后勤集团原料管理系统springboot+Layui+MybatisPlus+Shiro源代码

本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目描述后勤集团原料管理系统spr...

白卷开源SpringBoot+Vue的前后端分离入门项目

简介白卷是一个简单的前后端分离项目,主要采用Vue.js+SpringBoot技术栈开发。除了用作入门练习,作者还希望该项目可以作为一些常见Web项目的脚手架,帮助大家简化搭建网站的流程。...

Spring Security 自动踢掉前一个登录用户,一个配置搞定

登录成功后,自动踢掉前一个登录用户,松哥第一次见到这个功能,就是在扣扣里边见到的,当时觉得挺好玩的。自己做开发后,也遇到过一模一样的需求,正好最近的SpringSecurity系列正在连载,就结...

收藏起来!这款开源在线考试系统,我爱了

大家好,我是为广大程序员兄弟操碎了心的小编,每天推荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节省开发效率,实现不加班不熬夜不掉头发,是我的目标!今天小编推荐一款基于Spr...

Shiro框架:认证和授权原理(shiro权限认证流程)

优质文章,及时送达前言Shiro作为解决权限问题的常用框架,常用于解决认证、授权、加密、会话管理等场景。本文将对Shiro的认证和授权原理进行介绍:Shiro可以做什么?、Shiro是由什么组成的?举...

取消回复欢迎 发表评论: