日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

倒序查询_mysql大表分页查询翻页优化方案

發(fā)布時間:2025/3/20 数据库 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 倒序查询_mysql大表分页查询翻页优化方案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

mysql分頁查詢是先查詢出來所有數據,然后跳過offset,取limit條記錄,造成了越往后的頁數,查詢時間越長

一般優(yōu)化思路是轉換offset,讓offset盡可能的小,最好能每次查詢都是第一頁,也就是offset為0

查詢按id排序的情況

一、如果查詢是根據id排序的,并且id是連續(xù)的

這種網上介紹比較多,根據要查的頁數直接算出來id的范圍

比如offset=40, limit=10, 表示查詢第5頁數據,那么第5頁開始的id是41,增加查詢條件:id>40 limit 10

二、如果查詢是根據id排序的,但是id不是連續(xù)的

通常翻頁頁數跳轉都不會很大,那我們可以根據上一次查詢的記錄,算出來下一次分頁查詢對應的新的 offset和 limit,也就是離上一次查詢記錄的offset

分頁查詢一般會有兩個參數:offset和limit,limit一般是固定,假設limit=10

那為了優(yōu)化offset太大的情況,每次查詢需要提供兩個額外的參數

參數lastEndId: 上一次查詢的最后一條記錄的id

參數lastEndOffset: 上一次查詢的最后一條記錄對應的offset,也就是上一次查詢的offset+limit

  • 第一種情況(與第二種其實是一樣):跳轉到下一頁,增加查詢條件:id>lastEndId limit 10
  • 第二種情況:往下翻頁,跳轉到下任意頁,算出新的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
  • 第三種情況:往上翻頁,跳轉到上任意頁,根據id逆序 ,newOffset = lastEndOffset- offset - limit-1, 查詢條件:id
  • 三,如果查詢是根據其他字段,比如一般使用的創(chuàng)建時間(createTime)排序

    這種跟第二種情況差不多,區(qū)別是createTime不是唯一的,所以不能確定上一次最后一條記錄對應的創(chuàng)建時間,哪些是下一頁的,哪些是上一頁的

    這時候,增加一個請求參數lastEndCount:表示上一次查詢最后一條記錄對應的創(chuàng)建時間,有多少條是這同一時間的,這個根據上一次的數據統(tǒng)計

    根據第二種情況下計算出來的newOffset加上lastEndCount,就是新的offset,其他的處理方式和第二種一致

    java 示例:

    /**

    * 如果是根據創(chuàng)建時間排序的分頁,根據上一條記錄的創(chuàng)建時間優(yōu)化分布查詢

    *

    * @see 將會自動添加createTime排序

    * @param lastEndCreateTime

    * 上一次查詢的最后一條記錄的創(chuàng)建時間

    * @param lastEndCount 上一次查詢的時間為lastEndCreateTime的數量

    * @param lastEndOffset 上一次查詢的最后一條記錄對應的偏移量 offset+limit

    **/

    public Page page(QueryBuilder queryBuilder, Date lastEndCreateTime, Integer lastEndCount, Integer lastEndOffset,

    int offset, int limit) {

    FromBuilder fromBuilder = queryBuilder.from(getModelClass());

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

    總結

    以上是生活随笔為你收集整理的倒序查询_mysql大表分页查询翻页优化方案的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。