旗下导航:搜·么
当前位置:网站首页 > MySQL教程 > 正文

mysql大表分页查询翻页优化计划【MySQL教程】,mysql,大表分页查询,翻页,优化方案

作者:搜教程发布时间:2019-12-01分类:MySQL教程浏览:74评论:0


导读:mysql分页查询是先查询出来一切数据,然后跳过offset,取limit条纪录,造成了越往后的页数,查询时候越长平常优化思绪是转换offset,让offset尽量的小...

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

参数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<lastEndId offset newOffset limit 10 ,然后再经由过程代码逆序,获得准确递次的数据,注重:末了一页 offset + limit>=totalCount ,也就是算出来的newOffset 能够小于0, 所以末了一页的newOffset=0,limit = totalCount - offset
  3. 第三种状况:往上翻页,跳转到上恣意页,依据id逆序 ,newOffset = lastEndOffset- offset - limit-1, 查询前提:id<lastEndId offset newOffset limit 10 ,然后再经由过程代码逆序,获得准确递次的数据

三,假如查询是依据其他字段,比方平常运用的建立时候(createTime)排序

这类跟第二种状况差不多,区别是createTime不是唯一的,所以不能肯定上一次末了一条纪录对应的建立时候,哪些是下一页的,哪些是上一页的

这时候,增添一个要求参数lastEndCount:示意上一次查询末了一条纪录对应的建立时候,有若干条是这同一时候的,这个依据上一次的数据统计

依据第二种状况下计算出来的newOffset加上lastEndCount,就是新的offset,其他的处置惩罚方式和第二种一致

java 示例:

/**
	 * 假如是依据建立时候排序的分页,依据上一条纪录的建立时候优化散布查询
	 * 
	 * @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大表分页查询翻页优化计划的细致内容,更多请关注ki4网别的相干文章!

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


欢迎 发表评论: