mysql大表分页查询翻页优化方案


mysql大表分页查询翻页优化方案

mysql分页查询是先查询出来所有数据,然后跳过offset,取limit条记录,造成了越往后的页数,查询时间越长

一般优化思路是转换offset,让offset尽可能的小,最好能每次查询都是第一页,也就是offset为0

 

查询按id排序的情况

一、如果查询是根据id排序的,并且id是连续的

这种网上介绍比较多,根据要查的页数直接算出来id的范围

比如offset=40, limit=10, 表示查询第5页数据,那么第5页开始的id是41,增加查询条件:id>40  limit 10

 

二、如果查询是根据id排序的,但是id不是连续的

通常翻页页数跳转都不会很大,那我们可以根据上一次查询的记录,算出来下一次分页查询对应的新的 offset和 limit,也就是离上一次查询记录的offset

分页查询一般会有两个参数:offset和limit,limit一般是固定,假设limit=10

 那为了优化offset太大的情况,每次查询需要提供两个额外的参数

参数lastEndId: 上一次查询的最后一条记录的id

白瓜面试 白瓜面试

白瓜面试 - AI面试助手,辅助笔试面试神器

白瓜面试 162 查看详情 白瓜面试

参数lastEndOffset: 上一次查询的最后一条记录对应的offset,也就是上一次查询的offset+limit

  1. 第一种情况(与第二种其实是一样):跳转到下一页,增加查询条件:id>lastEndId limit 10
  2. 第二种情况:往下翻页,跳转到下任意页,算出新的newOffset=offset-lastEndOffset,增加查询条件:id>lastEndId offset newOffset limit 10,但是如果newOffset也还是很大,比如,直接从第一页跳转到最后一页,这时候我们可以根据id逆序(如果原来id是正序的换成倒序,如果是倒序就换成正序)查询,根据总数量算出逆序查询对应的offset和limit,那么 newOffset = totalCount - offset - limit, 查询条件:id=totalCount ,也就是算出来的newOffset 可能小于0, 所以最后一页的newOffset=0,limit = totalCount - offset
  3. 第三种情况:往上翻页,跳转到上任意页,根据id逆序 ,newOffset = lastEndOffset- offset - limit-1, 查询条件:id

 

三,如果查询是根据其他字段,比如一般使用的创建时间(createTime)排序

这种跟第二种情况差不多,区别是createTime不是唯一的,所以不能确定上一次最后一条记录对应的创建时间,哪些是下一页的,哪些是上一页的

这时候,增加一个请求参数lastEndCount:表示上一次查询最后一条记录对应的创建时间,有多少条是这同一时间的,这个根据上一次的数据统计

根据第二种情况下计算出来的newOffset加上lastEndCount,就是新的offset,其他的处理方式和第二种一致

 

j*a 示例:

 

/**
	 * 如果是根据创建时间排序的分页,根据上一条记录的创建时间优化分布查询
	 * 
	 * @see 将会自动添加createTime排序
	 * @param lastEndCreateTime
	 *            上一次查询的最后一条记录的创建时间
	 * @param lastEndCount 上一次查询的时间为lastEndCreateTime的数量
	 * @param lastEndOffset  上一次查询的最后一条记录对应的偏移量     offset+limit
	 **/
	public Page<T> page(QueryBuilder queryBuilder, Date lastEndCreateTime, Integer lastEndCount, Integer lastEndOffset,
			int offset, int limit) {
		FromBuilder fromBuilder = queryBuilder.from(getModelClass());
		Page<T> page = new Page<>();
		int count = dao.count(fromBuilder);
		page.setTotal(count);
		if (count == 0) {
			return page;
		}
		if (offset == 0 || lastEndCreateTime == null || lastEndCount == null || lastEndOffset == null) {
			List<T> list = dao.find(
					SelectBuilder.selectFrom(fromBuilder.offsetLimit(offset, limit).order().desc("createTime").end()));
			page.setData(list);
			return page;
		}
		boolean isForward = offset >= lastEndOffset;
		if (isForward) {
			int calcOffset = offset - lastEndOffset + lastEndCount;
			int calcOffsetFormEnd = count - offset - limit;
			if (calcOffsetFormEnd <= calcOffset) {
				isForward = false;
				if (calcOffsetFormEnd > 0) {
					fromBuilder.order().asc("createTime").end().offsetLimit(calcOffsetFormEnd, limit);
				} else {
					fromBuilder.order().asc("createTime").end().offsetLimit(0, calcOffsetFormEnd + limit);
				}
			} else {
				fromBuilder.where().andLe("createTime", lastEndCreateTime).end().order().desc("createTime").end()
						.offsetLimit(calcOffset, limit);
			}
		} else {
			fromBuilder.where().andGe("createTime", lastEndCreateTime).end().order().asc("createTime").end()
					.offsetLimit(lastEndOffset - offset - limit - 1 + lastEndCount, limit);
		}
		List<T> list = dao.find(SelectBuilder.selectFrom(fromBuilder));
		if (!isForward) {
			list.sort(new Comparator<T>() {
				@Override
				public int compare(T o1, T o2) {
					return o1.getCreateTime().before(o2.getCreateTime()) ? 1 : -1;
				}
			});
		}
		page.setData(list);
		return page;
	}

 

前端js参数,基于bootstrap table

    this.lastEndCreateTime = null;
    this.currentEndCreateTime = null;
    
    this.isRefresh = false;        
      this.currentEndOffset = 0;
        this.lastEndOffset = 0;
        this.lastEndCount = 0;
        this.currentEndCount = 0;
        $("#" + this.tableId).bootstrapTable({
            url: url,
            method: 'get',
            contentType: "application/x-www-form-urlencoded",//请求数据内容格式 默认是 application/json 自己根据格式自行服务端处理
            dataType:"json",
            dataField:"data",
            pagination: true,
            sidePagination: "server", // 服务端请求
            pageList: [10, 25, 50, 100, 200],
            search: true,
            showRefresh: true,
            toolbar: "#" + tableId + "Toolbar",
            iconSize: "outline",
            icons: {
                refresh: "icon fa-refresh",
            },
            queryParams: function(params){
            	if(params.offset == 0){
            		this.currentEndOffset = params.offset + params.limit;
            	}else{
            		if(params.offset + params.limit==this.currentEndOffset){ 
            			//刷新
            			this.isRefresh = true;
            			params.lastEndCreateTime = this.lastEndCreateTime;
                		params.lastEndOffset = this.lastEndOffset;
                		params.lastEndCount = this.lastEndCount;
            		}else{ 
            			console.log(this.currentEndCount);
            			//跳页
            			this.isRefresh = false;
            			params.lastEndCreateTime = this.currentEndCreateTime;
                		params.lastEndOffset = this.currentEndOffset;
                		params.lastEndCount = this.currentEndCount;
                		this.lastEndOffset = this.currentEndOffset;
                		this.currentEndOffset = params.offset + params.limit;
                		console.log(params.lastEndOffset+","+params.lastEndCreateTime);
                		
            		}
            	}
            	return params;
            },
            onSearch: function (text) {
                this.keyword = text;
            },
            onPostBody : onPostBody,
            onLoadSuccess: function (resp) {
            	
            	if(resp.code!=0){
            		alertUtils.error(resp.msg);
            	}
               
                var data = resp.data;
                var dateLength = data.length;
                if(dateLength==0){
                	return;
                }
                if(!this.isRefresh){
                	 this.lastEndCreateTime =  this.currentEndCreateTime;
                     this.currentEndCreateTime = data[data.length-1].createTime;
                     this.lastEndCount = this.currentEndCount;
                     this.currentEndCount = 0;
                     for (var i = 0; i < resp.data.length; i++) {
						var item = resp.data[i];
						if(item.createTime === this.currentEndCreateTime){
							this.currentEndCount++;
						}
					}
                }
                
            }
        });

更多MySQL相关技术文章,请访问MySQL教程栏目进行学习!

以上就是mysql大表分页查询翻页优化方案的详细内容,更多请关注其它相关文章!


# 可以根据  # 山西大地seo  # seo培训教程优化  # 电影网站推广什么产品好  # 恩施网站优化推广公司  # 怎么优化英语网站  # 智能家居案例网站推广  # 房地产网站建设西宁  # 台州网站的优化  # 河南网站建设优化推广  # 半岛影院seo  # 第一页  # mysql  # 算出来  # 下一页  # 解锁  # 跳转到  # 镜像  # 第二种  # 分页  # 优化方案  # 翻页  # 大表分页查询 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: 《kimi智能助手》制作ppt教程  汽水音乐官方网站登录入口_汽水音乐网页版进入链接  TikTok私信无法发送表情怎么办 TikTok消息表情发送修复方法  优酷下载视频的清晰度怎么选_优酷缓存清晰度设置与选择指南  J*aScript调试技巧_性能分析与内存快照  《咸鱼之王》新版孙坚技能解析  解决CSS background 属性中 cover 关键字的常见误用  风神瞳获取全攻略  如何高效地基于键列值映射DataFrame中的多个列  Sublime怎么快速复制文件路径_Sublime右键菜单增强技巧  Win10通知横幅停留时间修改 Win10自定义通知显示时长【技巧】  J*a中为什么强调组合优于继承_组合模式带来的灵活性与可维护性解析  J*a里如何处理ArithmeticException并防止除零_算术异常防护策略解析  如何使用CSS Grid实现“大方块左侧,小方块右侧垂直堆叠”的水平布局  mysql如何配置从库只读_mysql从库只读设置方法  Dash应用中自定义HTML页面标题与网站图标(F*icon)的实用指南  在VS Code中利用AI辅助进行代码迁移  多多买菜门店端app订单查看方法  PHP实现等比数列:构建数组元素基于前一个值递增的方法  抖音官网入口快速访问 抖音网页版账号注册解析  OpenWeatherMap API:通过城市名称获取天气预报数据指南  51漫画网实时入口 51漫画网页版官方免费漫画入口  Win10截图远程协助 Win10远程桌面截屏法【场景应用】  C++中std::thread和std::async的区别_C++并发编程与线程与异步任务比较  Flexbox布局中Stencil组件宽度不显示问题解析与:host尺寸控制  《兴业银行》注册登录方法  猫眼电影app如何参与官方的抽奖活动_猫眼电影官方抽奖参与方法  猫眼电影app怎么查询电影院的营业时间_猫眼电影影院营业时间查询教程  微信网页版在线登录 微信网页版在线使用入口  教资成绩怎么查询  《猎聘》筛选猎头岗位方法  解决Go encoding/json 将JSON大数字解析为浮点数的问题  口腔诊所管理软件推荐  《杖剑传说》食谱大全  VS Code源代码管理(SCM)视图的进阶使用技巧  t3出行如何使用微信支付  《异星探险家》古怪的物品作用介绍  响应式设计中动态背景颜色条的实现指南  PDF文件去水印平台入口 PDF水印删除网址  菜鸟裹裹怎样获得取件码_菜鸟裹裹获得取件码步骤  POKI小游戏在线免费入口链接 POKI小游戏无下载秒玩玩  Flask 应用中图片动态更新与上传:实现客户端定时刷新与服务器端文件管理  J*aScript中高效处理用户输入:从Keyup事件到表单提交的优化实践  Chart.js 教程:自定义插件实现图表与图例间距调整  汽水音乐网页端访问 汽水音乐官方网页直达  Flash AS3.0简易相册制作  c++如何使用std::thread::join和detach_c++线程生命周期管理  《i莞家》修改昵称方法  mysql怎么导入sql文件_mysql导入sql文件的方法与技巧  Cassandra中复合主键、二级索引与ORDER BY排序的限制与解决方案 

 2019-06-25

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.