如何高效分頁

zhangyf1121發表於2024-06-30

傳統的分頁,是基於offset進行分頁,如果頁碼數很大的情況下,每次都需要遍歷之前的offset+N條資料,
在分頁多的時候容易出現MySQL效能瓶頸,所以我們可以基於取前一頁的最大行數的id(將上次遍歷到的最末尾的資料ID傳給資料庫,然後直接定位到該ID處,再往後面遍歷資料)
然後根據這個最大的id來限制下一頁的起點

  • 這也是一種常見的MySQL最佳化手段

程式碼如下

    public IPage<User> getUsersByPage(int pageNum, int pageSize) {
        Long startId = getStartIdByPage(pageNum, pageSize);
        if (startId == null) {
            // 如果起始ID為null,說明沒有資料,返回空分頁
            return new Page<>(pageNum, pageSize, 0);
        }
        return getUsersAfterId(startId, pageSize);
    }


    public Long getStartIdByPage(int pageNum, int pageSize) {
        // 查詢第(pageNum - 1) * pageSize條記錄的最後一個主鍵ID
        int offset = (pageNum - 1) * pageSize;
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("id").last("LIMIT " + offset + ", 1");
        User user = userMapper.selectOne(queryWrapper);
        return user != null ? user.getId() : null;
    }


    public IPage<User> getUsersAfterId(Long startId, int limit) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.gt("id", startId - 1);
        Page<User> page = new Page<>(1, limit);
        return userMapper.selectPage(page, queryWrapper);
    }

相關文章